WILD
====
A simple string search routine using wildcards
This routine was originally filched from some computer magazine way back
in the mists of time. I no longer remember whether it was writtten in
SuperBASIC or some other language, but I re-worked it and patched it over
the years and have also translated it into assembler a couple of times.
I present it in different versions, as they each have their place,
depending on what you want to do. For simple day-to-day usage this version
is usually adequate.
Usage:
------
found% = WILD%(pattern$, string$)
Where
found% is a relatively meaningless number indicating whether the
pattern was found in the string (+ve) or not (0)
pattern$ may contain the following wildcard characters:
? => matches any one character in the search string
* => matches any number of characters, including none
/ => cancels the following wildcard character, including
itself, ie the character following is to be taken
literally.
string$ is the string to be searched
Examples:
---------
PRINT WILD%("abc", "ABC") => 3
PRINT WILD%("a?c", "ABC") => 3
PRINT WILD%("a*", "ABC") => 2
PRINT WILD%("???", "ABC") => 3 (three matching characters)
PRINT WILD%("?*", "ABC") => 2 (at least one character)
Note, however:
PRINT WILD%("*?", "ABC") => 0 (!)
because
PRINT WILD%("*A", "ABC") => 0
however,
PRINT WILD%("*C", "ABC") => 3
and
PRINT WILD%("?*", "ABC") => 2 (at least one character)
Cancel:
PRINT WILD%("a/?c", "A?C") => 3
PRINT WILD%("ab/*", "AB*") => 3
PRINT WILD%("ab/*", "ABC") => 0
etc..
WILD% doesnt check the syntax of the pattern string, so patterns like
PRINT WILD%("A/BC", "ABC") => 0
PRINT WILD%("A/BC", "abc") => 0
PRINT WILD%("A/bC", "abc") => 3
PRINT WILD%("AbC/", "abc") => 3
which are all mistakes, will give spurious answers.
WILD% uses a simple case translation routine that covers the traditional
Qdos (UK) ASCII character set, but may not be suitable for "foreign"
versions.
Note: Due to the way the cancel character has been implemented, characters
0, 1 & 2 (ie CHR$(0)..CHR$(2)) are reserved and cannot form part of either
the pattern or search strings!
S*BASIC
-------
The original code looks something like this:
100 DEFine FuNction WLD(pat$, str$)
110 LOCal loop, i, j, ls, p$(40)
120 IF str$ = '' THEN
130 IF pat$ = '':RETurn 1:ELSE :RETurn 0
140 END IF
150 p$ = pat$ & CHR$(0): REMark Sentinel
160 i = 1: j = 1: ls = 1
170 REPeat loop
180 IF p$(j) = '*' THEN
190 j = j + 1: ls = j
200 IF j = LEN(p$) THEN
210 IF LEN(p$) = 2 THEN
220 RETurn 1
230 ELSE
240 RETurn i
250 END IF
260 END IF
270 END IF
280 IF p$(j) INSTR str$(i) & '?' THEN
290 i = i + 1: j = j + 1
300 ELSE
310 IF ls = 1: RETurn 0
320 i = i - j + ls + 1: j = ls
330 END IF
340 IF j > LEN(p$) OR i > LEN(str$): EXIT loop
350 END REPeat loop
360 IF j = LEN(p$) - 1 AND p$(LEN(p$) - 1) = '*': RETurn i
370 IF i <LEN(str$) OR j < LEN(p$): RETurn 0
380 RETurn i
390 END DEFine
400 :
It is also perfectly usable, however it uses a sentinel and has no cancel
character. The assembler version included here, was originally a more or
less direct translation of this code, which is why it may look a bit
contrived. Apart from the modifications mentioned, I havent bothered to
change it much, as it is fiddly work and it seems to work well as it
stands!
V0.03, pjw, May 23rd 2019
Conditions of use and DISCLAIMER as per Knoware.no
QL Software
