![]() |
Re: Match funktion?
Zitat:
...und mein erster Post war eigentlich nur eine Reaktion auf mirages, der auf einen Satz in Mthias' Beitrag reagiert hat... :freak: |
Re: Match funktion?
ohne jetzt wirklich alles gelesen zu haben. Hast du schonmal versucht statt einem ? ein + zu verwenden? Ich meine, das wäre nämlcih für diesen Zweck...
|
Re: Match funktion?
Mit "zu dick" meinte ich, dass ich reguläre Ausdrücke gleich für zu aufwändig halte. In meinem Fall. Außerdem müsste ich dann vermutlich die Syntax meiner XML-Datei ändern (schon wieder :?), weil die Strings aus einer solchen kommen. Darum dachte ich, es gibt vllt. eine einfach Möglichkeit, schnell zwei Strings miteinander zu vergleichen, wenn einer die typischen DOS-Wildcards * und ? benutzt. Ich habe nichts gegen reguläre Ausdrücke, aber in dem Fall wäre es für mich wie "mit Kanonen auf Spatzen ..." ;)
Muss ich Robert jetzt etwa auch küssen? :gruebel: |
Re: Match funktion?
Hi,
ich hab dafür folgenden Code geschrieben, den ich allerdings erst 2 Wochen testen konnte, also ohne Gewähr ;) Für Verbesserungen bin ich jederzeit offen:
Delphi-Quellcode:
Edit: Folgende Funktion wird auch benötigt:
// Erlaubte Wildcards:
// * = alles oder nichts // ? = einzelnes zeichen MUSS vorkommen // # = Zahl MUSS vorkommen function WildCardMatch(const check, mask:string):boolean; var _next_wc:integer; a,b:string; function find_wildcard(const _check:string):integer; begin if (Pos('*',_check) = 0) then if (Pos('?',_check) = 0) then if (Pos('#',_check) = 0) then result:=-1 else result:=Pos('#',_check) else result:=Pos('?',_check) else result:=Pos('*',_check); end; function parse_from_wc(const wildcard, _check:string):boolean; var next_wc,off_set,first_of:integer; t,tmp:string; begin result:=true; if (copy(wildcard,1,1) = '#') then begin if (length(_check) = 0) or (not IsNumber(copy(_check,1,1))) then begin result:=false; exit; end; t:=copy(wildcard,2,length(wildcard)); next_wc:=find_wildcard(t); if (next_wc = -1) then result:=true else begin tmp:=copy(wildcard,2,next_wc-1); if (length(tmp) = 0) then begin result:=false; exit; end else if (IsNumber(copy(_check,1,length(tmp)))) then if (not parse_from_wc(copy(wildcard,next_wc+1,length(wildcard)),copy(_check,next_wc+1,length(_check)))) then begin result:=false; exit; end else else begin result:=false; exit; end; end; end else if (copy(wildcard,1,1) = '?') then begin if (length(_check) = 0) then begin result:=false; exit; end; t:=copy(wildcard,2,length(wildcard)); next_wc:=find_wildcard(t); if (next_wc = -1) then result:=(t = copy(_check,2,length(_check))) else begin tmp:=copy(wildcard,2,next_wc-1); if (length(tmp) = 0) then begin result:=false; exit; end else if (not parse_from_wc(copy(wildcard,next_wc+1,length(wildcard)),copy(_check,next_wc+1,length(_check)))) then begin result:=false; exit; end; end; end else if (copy(wildcard,1,1) = '*') then begin t:=copy(wildcard,2,length(wildcard)); next_wc:=find_wildcard(t); if (next_wc = -1) then begin if (length(_check) >= length(t)) then result:=(copy(_check,1+length(_check)-length(t),length(_check)) = t) else result:=false; exit; end else begin if (next_wc = 0) then begin result:=parse_from_wc(copy(wildcard,2,length(wildcard)),_check); exit; end else begin off_set:=1; tmp:=copy(wildcard,2,next_wc-1); while (true) do begin first_of:=Pos(tmp,copy(_check,off_set,length(_check))); if (first_of = 0) then begin result:=false; exit; end else begin off_set:=first_of+length(tmp); if (parse_from_wc(copy(wildcard,next_wc+2,length(wildcard)), copy(_check,off_set,length(_check)))) then begin result:=true; exit; end; end; end; end; end; end; end; begin if (length(check) = 0) then begin result:=false; exit; end; result:=true; _next_wc:=find_wildcard(mask); if (_next_wc = 0) then result:=parse_from_wc(mask,check) else if (_next_wc = -1) then result:=(check = mask) else begin a:=copy(check,1,_next_wc-1); b:=copy(mask,1,_next_wc-1); if (a <> b) then begin result:=false; exit; end; if (not parse_from_wc(copy(mask,_next_wc,length(mask)-_next_wc+1), copy(check,_next_wc,length(check)-_next_wc+1))) then begin result:=false; exit; end; end; end;
Delphi-Quellcode:
Viel Spaß ;)
function IsNumber(const s:string): Boolean;
var c:integer; const nums:string = '0123456789'; begin result:=(length(s) > 0); for c:=1 to length(s) do if (Pos(copy(s,c,1),nums) = 0) then begin result:=false; Break; end; end; cu |
Re: Match funktion?
Zitat:
![]() ![]() |
Re: Match funktion?
Hi,
@MathiasSimmack: Ich programmiere nicht so gern mit Exceptions, das ist für mich so die Hau-Drauf-Methode à la "Frag ihn nicht ob das eine Platzwunde ist, drück drauf und wenn er schreit ist es eine" ;) Ist die Methode mit Exceptions denn erheblich schneller als meine? cu |
Re: Match funktion?
Was heißt schneller? Es ging nur um die Ziffernerkennung:
Delphi-Quellcode:
ist ebenso elegant wie
try
StrToInt(stringVariable); Result := true; except Result := false; end;
Delphi-Quellcode:
Auf jeden Fall ist beides vermutlich besser als der Weg, den du gewählt hast. :stupid: Zumal deine Funktion bei einer negativen Zahl wie -1,-2, ... versagen würde. ;)
Val(stringVariable, integerVariable, errorCode);
Result := errorCode = 0; |
Re: Match funktion?
Zitat:
Wenn du das ganze Stringkopieren sein lässt und einfach einen PChar auf den Eingabe string legst (Durch den kannst du easy per increment iterieren. ;) ),dürfte auch deine nicht mehr so lagsam sein, bzw. nicht mehr so viel Speicher verbraten. Und wie MS schon sagte... bei deiner gehen nur positive ints. ;) |
Re: Match funktion?
Hi,
gut, mag sein. In meinem Fall will ich aber nur positive Ganzzahlen zulassen, von daher brauch ich die negativen gar nicht zu beachten ;) Wer in den Wildcards auch negative Zahlen zulassen will kann ja den von MathiasSimmack geposteten Vorschlag verwenden. Danke für die Vorschläge, cu |
Re: Match funktion?
danke euch allen :)
Ich hab mich für Mathias Simmacks's Funktion entschieden. @Mathias: Kannst du mir noch erklären, wie bzw warum die funktion 2mal existiert? bzw sie unterteilt ist? Edit: Und kann ich die Funktion irgendwie in eine Klasse packen so das sie von aussen nicht sichtbar ist? Hier:
Delphi-Quellcode:
meint der compiler das external ein feld sei und es damit nicht nach einer funktion erlaubt ist...
TIAL = class(TObject)
private function PathMatchSpec(pszFile, pszSpec: PAnsiChar): bool; stdcall; external 'shlwapi.dll' name 'PathMatchSpecA'; public end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:11 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz