Jeder kennt sie, die Zeichen '?' und '', die man in der Fileselectorbox verwendet, um nur zwischen bestimmten Dateien wählen zu müssen. Dabei bedeutet das ’?', dass an dieser Stelle jedes beliebige Zeichen stehen darf, und der '' ersetzt eine beliebige Anzahl von Zeichen (auch 0). Wenn Sie z.B. in der Fileselectorbox die '*.BA?' einstellen, werden nur die Files angezeigt, die links eine beliebige Anzahl von Zeichen besitzen, dann folgen ein Punkt, ein 'B' und ein 'A' und am Schluss noch 1 beliebiges Zeichen. Es sind also alle Dateien der Extension BAS,BAK ... gemeint.
Solche Wildcards werden jedoch nicht nur auf Dateinamen angewandt. Auch so manches Textverarbeitungs- (z.B. Tempus) oder Datenbankprogramm verwendet sie ebenfalls. Die Pascal-Funktion maskepasst(...) ermöglicht auch Ihnen, auf einfache Weise Wildcards zu verwenden. Damit steht Ihrem Adressenverwaltungsprogramm, das alle 'H. Meier' ausdrucken kann, egal wie 'Meier' geschrieben wird ('H* M??er'). nichts mehr im Wege.
Fmaskepasst('?','*', maske, string) THEN WRITELN('paßt');
überprüft, ob string auf die Maske maske paßt. Wenn ja, wird paßt geschrieben. In diesem Beispiel wäre das Ersatzzeichen für 1 Zeichen. Existenzquantor genannt, ein '?' und für beliebig viele Zeichen, den Allquantor, ein '*'. Selbstverständlich dürfen hier auch andere Zeichen verwendet werden.
Das Beispielprogramm demonstriert die Arbeitsweise der Funktion. Es lädt eine beliebige Textdatei, deren Namen sie eingeben und druckt alle Zeilen aus. Diejenigen Zeilen, die auf Ihre Maske passen, werden dabei invers geschrieben.
Wie aber arbeitet die Funktion? Sie vergleicht von links beginnend Buchstabe für Buchstabe der Maske und des Strings. Unterscheiden sich die beiden Buchstaben, wird die Funktion beendet und FALSE zurückgegeben. Ist das Zeichen in der Maske jedoch '?', wird auf jeden Fall mit den nächsten beiden Zeichen fortgefahren. Schwierig wird es erst, wenn in der Maske ein '' angetroffen wird. Die Funktion ruft sich dann selbst rekursiv auf. Als Maske wird der Rest der Maske hinter dem '' übergeben und als der zu untersuchende String nacheinander erst der Teil-String vom dem Zeichen ab, das an dergleichen Stelle steht wie der '*' in der Maske, bis zum rechten Ende, dann 1 Zeichen danach bis zum Ende usw. Paßt irgendeiner dieser Teil-Strings auf die Maske, paßt auch der gesamte String auf die gesamte Maske, es wird TRUE zurückgegeben, sonst FALSE. Dieses Verfahren ist in der Unterfunktion alltest(...) festgelegt. Aus Zeitgründen wurde der eigentliche Vergleich in die Unterfunktion passt(...) verlegt, damit nicht für jeden rekursiven Aufruf alle Parameter neu übergeben werden müssen.
program wildcarddemo;
{
Wildcards in Pascal
von R. Wisser
(c) MAXON Computer
}
type str=string[255];
var dat : text;
fn,s,maske : str;
{ -----Beginn der Funktion ------- }
function maskepasst( existenz,all:char; var maske,s:str ):boolean;
var mlen,slen,i:integer;
function passt( mpos,spos:integer ):boolean;
var passtnicht,passt_exist:boolean;
function alltest( mpos,spos:integer ):boolean;
var existiert:boolean;
begin { alltest }
existiert:=(mpos>mlen);
while (spos<=slen) and not existiert do
begin
if passt(mpos,spos) then existiert:=true
else spos:=spos+1
end;
alltest:=existiert
end; { alltest }
begin { passt }
passtnicht:=false; passt_exist:=false;
while (mpos<=mlen) and (not passt_exist) and not passtnicht do
begin
if maske[mpos]=all then
begin
passt_exist:=alltest(mpos+1,spos);
if not passt_exist
then passtnicht:=true;
end
else if spos>slen
then passtnicht:=true
else if maske[mpos]<>existenz then
if maske[mpos]<>s[spos] then passtnicht:=true;
mpos:=mpos+1; spos:=spos+1;
end;
if passt_exist then passt:=true
else if passtnicht then passt:=false
else passt:=(mpos>mlen) and (spos>slen);
end; { passt }
begin { maskepasst }
mlen:=length(maske); slen:=length(s);
maskepasst:=passt(1,1)
end; { maskepasst }
{ ------------------- }
begin
write('Filename : '); readln(fn);
write('Maske : '); readln(maske);
writeln; writeln;
reset(dat,fn);
while not eof(dat) do
begin
readln(dat,s);
if maskepasst('?','*',maske,s) then
begin
write(chr(27),'p'); writeln(s);write(chr(27),'q');
end
else writeln(s)
end
end.