Hallo,
hier kommt eine
Unit für den Stringvergleich mit Wildcards.
Als
Wildcards sind
*(beliebig viele Zeichen) und
? (ein beliebiges Zeichen) zulässig.
Diese
Unit wird verwendet, wenn eine Regular Expression Library für das
Problem ein Overkill wäre.
Die Kernfunktion
CompareWildString arbeitet mit Zeigern und der berühmt-berüchtigten GOTO-Anweisung;
deshalb sind Tests unerlässlich.
Die
Unit wurde mit
DUnit getestet.
Hier die Testfälle:
CheckEquals(True, CompareWildText('ABC', 'ABC'));
CheckEquals(True, CompareWildText('ABC*', 'ABC'));
CheckEquals(True, CompareWildText('A?C', 'ABC'));
CheckEquals(True, CompareWildText('*???', 'ABC'));
CheckEquals(True, CompareWildText('H?llo W*', 'Hallo Welt!'));
CheckEquals(True, CompareWildText('h?llo W*', 'Hello World!'));
CheckEquals(True, CompareWildText('H?llo W*d!', 'Hello World!'));
CheckEquals(False, CompareWildText('H?llo W*d', 'Hello World!'));
Und hier nun die
Unit wcomp:
Delphi-Quellcode:
unit wcomp;
interface
// case-sensitive (Gross/Kleinschreibung wird beachtet)
function CompareWildString(
const wild,
Name :
string) : Boolean;
// case-insensitive (Gross/Kleinschreibung ingorieren)
function CompareWildText(
const wild,
Name :
string) : Boolean;
implementation
uses SysUtils;
const MAXB = 8;
(*
* Compare a wild card name with a normal name.
* Taken from Matt Dillon's csh program.
*)
function CompareWildString(
const wild,
Name :
string) : Boolean;
label goback;
var
w : PChar;
n : PChar;
back :
array[0..MAXB-1, 0..1]
of PChar;
s1, s2 : char;
bi : integer;
begin
w := PChar(wild);
n := PChar(
Name);
bi := 0;
while (n^ <> #0)
or (w^ <> #0)
do
begin
case w^
of
'
*':
begin
if bi = MAXB
then
begin
raise Exception.CreateFmt('
CompareWildString(%s, %s)'#13#10+
'
too many levels of ''
*''
', [wild,
Name]);
end;
back[bi, 0] := w;
back[bi, 1] := n;
Inc(bi);
Inc(w);
continue;
goback:
Dec(bi);
while (bi >= 0)
and (back[bi,1]^ = #0)
do
Dec(bi);
if bi < 0
then
begin
Result := False;
Exit;
end;
w := back[bi,0];
Inc(w);
Inc(back[bi,1]);
n := back[bi,1];
Inc(bi);
continue;
end;
'
?':
begin
if n^ = #0
then
begin
if bi > 0
then
goto goback;
Result := False;
Exit;
end;
end;
else // default
begin
s1 := n^;
s2 := w^;
if s1 <> s2
then
begin
if bi > 0
then
goto goback;
Result := False;
Exit;
end;
end;
// default
end;
// case ...
if n^ > #0
then
Inc(n);
if w^ > #0
then
Inc(w);
end;
Result := True;
end;
function CompareWildText(
const wild,
Name :
string) : Boolean;
begin
Result := CompareWildString(AnsiUpperCase(wild), AnsiUpperCase(
Name));
end;
end.
[edit=Matze]Code formatiert. Mfg, Matze[/edit]