Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Like unter Delphi (https://www.delphipraxis.net/90808-like-unter-delphi.html)

smudo 24. Apr 2007 09:29


Like unter Delphi
 
Hallo,

ich suche eine Funktion unter Delphi, welche mir zwei Strings so miteinander vergleicht, wie es in einer DB "like" macht.
Kennt sich da vllt. jemand aus?

Danke im Voraus
René

Nikolas 24. Apr 2007 09:31

Re: Like unter Delphi
 
Ich kenne die Funktion zwar nicht, denke mir aber, dass die z.B. die Levenstein-Distanz weiterhelfen könnte.

smudo 24. Apr 2007 09:43

Re: Like unter Delphi
 
Also, Like vergleicht zwei Strings mit Platzhaltern und ohne Beachtung der Gross- und Kleinschreibung.
Letzteres ist ja kein Problem, aber die Platzhalter machen mir zu schaffen.

für D%p?ie ergibt Like:
  • True bei folgenden Begriffen: delphi, delpie, dpie
  • False bei folgenden Begriffen: delpfhie, elphi, delphy

Solch ein Vergleich muss doch auch unter Delphi möglich sein, eventuell mit AnsiResemblesText (SoundEx, RegEx...?)

marabu 24. Apr 2007 09:47

Re: Like unter Delphi
 
Hallo,

es gibt kein reguläres Pascal-Sprachmittel für deinen Test, aber selbstverständlich kannst du dir eine Funktion schreiben oder eine RegEx-Unit verwenden.

Grüße vom marabu

CK_CK 24. Apr 2007 09:48

Re: Like unter Delphi
 
Hi!
Sowas macht man mit regulären Ausdrücken.

Ich hab' mal ein Programm geschrieben, was dir beim entwickeln der Ausdrücke hilft: [KLICK]

Viele Grüße,
Chris

Schubi 24. Apr 2007 09:53

Re: Like unter Delphi
 
Da hilft dir folgende Unit:

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.
In Str1 darfst du dann * und ? einbauen, wie in der Windows-Suche.
Delphi-Quellcode:
CompareWildText(Str1, Str2)

sakura 24. Apr 2007 09:55

Re: Like unter Delphi
 
Zitat:

Zitat von marabu
es gibt kein reguläres Pascal-Sprachmittel für deinen Test

Nur weil Du nicht alle Delphi-Klassen kennst... ;-) Maskenvergleiche mit * (nicht %) und ? gibt es in der Unit Masks und der Klasse TMask. Die Anwendung ist selbsterklärend.

Masks wurde eigentlich für Dateinamenvergleiche geschaffen, funktioniert aber auch bei normalen Strings zuverlässig.

...:cat:...

smudo 24. Apr 2007 10:01

Re: Like unter Delphi
 
Ich bin erstmal überwältigt von der Flut der Antworten. Ich werde die Vorschläge unter die Lupe nehmen und mich zu meinem Resultat äußern.

Schubi 24. Apr 2007 10:23

Re: Like unter Delphi
 
Zitat:

Zitat von sakura
Zitat:

Zitat von marabu
es gibt kein reguläres Pascal-Sprachmittel für deinen Test

Nur weil Du nicht alle Delphi-Klassen kennst... ;-) Maskenvergleiche mit * (nicht %) und ? gibt es in der Unit Masks und der Klasse TMask. Die Anwendung ist selbsterklärend.

Masks wurde eigentlich für Dateinamenvergleiche geschaffen, funktioniert aber auch bei normalen Strings zuverlässig.

...:cat:...

Delphi-Quellcode:
uses Masks;
[...]
procedure TForm1.Button1Click(Sender: TObject);
var
  Mask : TMask;
begin
  Mask := TMask.Create(Edit1.Text);
  If Mask.Matches(Edit2.Text) Then Button1.Caption := 'True'
  else Button1.Caption := 'False';
  Mask.Destroy;
end;
:thumb:
Danke Miezekatze :-D
Kannte ich auch nicht.
Ist auch etwas Umständlich so fürs Erste, aber man kann das ja verpacken.

marabu 24. Apr 2007 11:15

Re: Like unter Delphi
 
Danke auch von mir - die Kapsel ist ja schon da: MatchesMask()

Mit Pascal-Sprachmittel wollte ich allerdings ausdrücken, dass pattern matching keine intrinsische Funktionalität von Pascal ist - im Gegensatz zu Perl und Mumps und ...

Freundliche Grüße

Muetze1 24. Apr 2007 11:17

Re: Like unter Delphi
 
Falls ihr OpenSource etc baut, dann weise ich hier mal darauf hin, dass die Unit Masks nicht in den Personal Editionen von Delphi enthalten waren/sind. Ich habe deshalb auch eine eigene Implementation schreiben müssen für meine XMLLib. Im Archiv ist die Funktion enthalten, Link in der Signature...

Ansonsten gibt es ab (D6?) D7 in der StrUtils die Funktion Delphi-Referenz durchsuchenSoundExSimilar() welche hierbei vllt. auch hilfreich ist, wobei die Funktion eher auf ähnliche Aussprache achtet als auf ähnliche Schreibweise...

sakura 24. Apr 2007 11:24

Re: Like unter Delphi
 
Zitat:

Zitat von Muetze1
wobei die Funktion eher auf ähnliche Aussprache achtet

und dazu nur in Englisch und ähnlich auszusprechenden Sprachen ;)

...:cat:...

smudo 25. Apr 2007 12:34

Re: Like unter Delphi
 
Ich habs vorerst mit der von Schubi geposteten Methode gelöst - nur anstelle des * das % verwendet.

Mehr würde mich aber die Möglichkeit über die regulären Ausdrücke interessieren. Das Programm von Chris habe ich dafür schon mal benutzt, bin allerdings auf diesem Gebiet noch völlig unbewandert:
  • eine Like-Abfrage z.B. für reg% Ausdr?ck* scheint mit RegEx so auszusehen: reg[ /.äöü\w]* Ausdr[ äöü\w]ck[ äöü\w]*
    damit finde ich reguläre Ausdrücke, reg. Ausdrücke, reg. Ausdruck
    Liege ich damit richtig
  • Ich habe keinen Plan, wie ich diesen (oder einen besseren) regulären Ausdruck unter Delphi verwenden kann

CK_CK 25. Apr 2007 12:43

Re: Like unter Delphi
 
Hi!
Für reguläre Ausdrücke kann ich den Wikipedia-Artikel dazu empfehlen. Da wird die ganze Syntax perfekt beschrieben.

Für Delphi gibt's z.B. [DIESE] Unit. Die funktioniert schön schnell und versteht auch die Perl-Extensions. Da ist auch eine (deutsche) Dokumentation dabei.

Viele Grüße,
Chris

Zacherl 25. Apr 2007 14:11

Re: Like unter Delphi
 
Guckst du hier:

Delphi-Quellcode:
function Like(const AString, APattern: String): Boolean;
var
  StringPtr, PatternPtr: PChar;
  StringRes, PatternRes: PChar;
begin
  Result:=false;
  StringPtr:=PChar(AString);
  PatternPtr:=PChar(APattern);
  StringRes:=nil;
  PatternRes:=nil;
  repeat
    repeat
      case PatternPtr^ of
        #0: begin
          Result:=StringPtr^=#0;
          if Result or (StringRes=nil) or (PatternRes=nil) then
            Exit;
          StringPtr:=StringRes;
          PatternPtr:=PatternRes;
          Break;
        end;
        '*': begin
          inc(PatternPtr);
          PatternRes:=PatternPtr;
          Break;
        end;
        '?': begin
          if StringPtr^=#0 then
            Exit;
          inc(StringPtr);
          inc(PatternPtr);
        end;
        else begin
          if StringPtr^=#0 then
            Exit;
          if StringPtr^<>PatternPtr^ then begin
            if (StringRes=nil) or (PatternRes=nil) then
              Exit;
            StringPtr:=StringRes;
            PatternPtr:=PatternRes;
            Break;
          end
          else begin
            inc(StringPtr);
            inc(PatternPtr);
          end;
        end;
      end;
    until false;
    repeat
      case PatternPtr^ of
        #0: begin
          Result:=true;
          Exit;
        end;
        '*': begin
          inc(PatternPtr);
          PatternRes:=PatternPtr;
        end;
        '?': begin
          if StringPtr^=#0 then
            Exit;
          inc(StringPtr);
          inc(PatternPtr);
        end;
        else begin
          repeat
            if StringPtr^=#0 then
              Exit;
            if StringPtr^=PatternPtr^ then
              Break;
            inc(StringPtr);
          until false;
          inc(StringPtr);
          StringRes:=StringPtr;
          inc(PatternPtr);
          Break;
        end;
      end;
    until false;
  until false;
end;
Das hab ich hier mal irgendwo im Forum gefunden ..

DP-Maintenance 26. Apr 2007 05:44

DP-Maintenance
 
Dieses Thema wurde von "Sharky" von "Datenbanken" nach "Object-Pascal / Delphi-Language" verschoben.
Das ist hier sicher besser aufgehoben.

dominikkv 26. Apr 2007 18:27

Re: Like unter Delphi
 
Hier -> * klick * hab ich was gefunden mit dem du vergleichen kannst zu wie viel % 2 strings gleich sind... vllt kannst du damit was anfangen.

edit:
und hier kannst du auch mal vorbeischauen

smudo 2. Mai 2007 12:56

Re: Like unter Delphi
 
@dominikkv: Dein zweiter Link entspricht dem, was andere schon hier gepostet haben, was auch wirklich gut funktioniert und was meine Frage beantwortet. Für mich blieb nur noch offen, wie man das Ganze mit regulären Ausdrücken machen kann (vielen Dank an CK_CK)

Der erste Link klang auch ganz spannend, ist aber leider nach genauerem Hinsehen ziemlich dürftig...

Vielen Dank an alle

René


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:44 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz