Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Match funktion? (https://www.delphipraxis.net/45125-match-funktion.html)

Robert_G 1. Mai 2005 00:32

Re: Match funktion?
 
Zitat:

Zitat von Pseudemys Nelsoni
die MatchesMask() Funktion geht hierfür nicht, da der Joker "?" dort heisst das ein Zeichen vorkommen KANN, aber nicht MUSS.... ich brauch aber das "muss".

;)

...und mein erster Post war eigentlich nur eine Reaktion auf mirages, der auf einen Satz in Mthias' Beitrag reagiert hat... :freak:

yankee 1. Mai 2005 01:13

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...

MathiasSimmack 1. Mai 2005 07:41

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:

sECuRE 1. Mai 2005 08:25

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:
// 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;
Edit: Folgende Funktion wird auch benötigt:
Delphi-Quellcode:
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;
Viel Spaß ;)
cu

MathiasSimmack 1. Mai 2005 08:32

Re: Match funktion?
 
Zitat:

Zitat von sECuRE
Edit: Folgende Funktion wird auch benötigt:
Delphi-Quellcode:
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;
Viel Spaß ;)

Mach dich mal über Delphi-Referenz durchsuchenVal schlau. Das dürfte einfacher sein. :stupid: Delphi-Referenz durchsuchenStrToInt in Verbindung mit try/except ginge auch. Deine andere Funktion habe ich mir nicht angeschaut. Zuviel für mich am Sonntag Morgen. :mrgreen:

sECuRE 1. Mai 2005 12:24

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

MathiasSimmack 1. Mai 2005 12:31

Re: Match funktion?
 
Was heißt schneller? Es ging nur um die Ziffernerkennung:
Delphi-Quellcode:
try
  StrToInt(stringVariable);
  Result := true;
except
  Result := false;
end;
ist ebenso elegant wie
Delphi-Quellcode:
Val(stringVariable, integerVariable, errorCode);
Result := errorCode = 0;
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. ;)

Robert_G 1. Mai 2005 12:34

Re: Match funktion?
 
Zitat:

Zitat von sECuRE
Ist die Methode mit Exceptions denn erheblich schneller als meine?

Ganz sicher ist sie das. ;)
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. ;)

sECuRE 1. Mai 2005 13:07

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

Pseudemys Nelsoni 10. Mai 2005 04:41

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:
  TIAL = class(TObject)
  private
    function PathMatchSpec(pszFile, pszSpec: PAnsiChar): bool; stdcall; external 'shlwapi.dll' name 'PathMatchSpecA';
  public

  end;
meint der compiler das external ein feld sei und es damit nicht nach einer funktion erlaubt ist...


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:11 Uhr.
Seite 2 von 3     12 3      

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