AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Stringvergleich mit Wildcards

Ein Thema von Willie1 · begonnen am 12. Dez 2008 · letzter Beitrag vom 11. Feb 2010
Antwort Antwort
Seite 4 von 5   « Erste     234 5      
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#31

Re: Stringvergleich mit Wildcards

  Alt 22. Jun 2009, 16:39
menno ... ich schau mal

eigentlich dachte ich, diesbezüglich hätt ich nichts verändert

hatte grad nur noch einen Parameter nachgetragen, damit bei den "wiederholenden" Aufrufen die äußeren und eventuell recht großen Strings nicht mit im Result landen (führendes und letztes * in der Abfrage).
(siehe nächster Beitrag)

ich glaub ich bau so'nen Assert mal mit in die Unit direkt ein ... so auch für die Zukunft
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#32

Re: Stringvergleich mit Wildcards

  Alt 22. Jun 2009, 19:20
das ist eigentlich zu peinlich zum Erwähnen:
meine Tests hatte ich, da es einfacher zum Debuggen war, meißt direkt mir der Hauptgrundfunktion gemacht und da traten einige Fehler nicht auf ...
z.B. wie der 1-Startindex bei String, welcher nicht als 0-Index für PChar angegeben wurde
und ein Copy&Paste-Fehler, wo Result gleich mit True initialisiert wurde, anstatt mit False

nja, hatte jetzt dabei auch gleich noch eine Idee bekommen, wie der Vergleich vorzeitig abbrechen kann, wenn das letzte Maskenzeichen ein * ist ... bislang wurde dennoch der restliche Stringinhalt geprüft.

und wie schon erwähnt, funktioniert nun auch sowas: suchen folgender Masken in einem String:
wenn Maskenanfang und -ende * lauten, dann wird das dazwischen gesucht und zusammen mit dem neuen cfIgnoreOuterAsterix kann man so auch "recht" speichersparend den einen String nach allen Vorkommen der "Teil"Maske (ohne erstes und letztes * ) durchforsten
Delphi-Quellcode:
Var S, Sr: String;
  i, i2: Integer;
  X: TStringDynArray;

Begin
  S := 'i|F1|V1|F2|i'
    + 'i|F1|V2|F2|i'
    + 'i|F1|V3|F2|i';

  i := 1;
  i2 := -1;
  While True do Begin
    X := MatchStringEx('*F1*F2*', S, [], i, i);
    If X = nil Then Break;
    Sr := X[1];
    Inc(i2);

    ShowMessage('1:'#13#10'Sr[' + IntToStr(i2) + '] = "' + Sr + '"');
  End;



  i := 1;
  i2 := -1;
  While True do Begin
    X := MatchStringEx('*F1*F2*', S, [cfIgnoreOuterAsterix], i, i);
    If X = nil Then Break;
    Sr := X[0];
    Inc(i2);

    ShowMessage('2:'#13#10'Sr[' + IntToStr(i2) + '] = "' + Sr + '"');
  End;



  i := MatchStringCount('*F1*F2*', S, []);

  ShowMessage('3:'#13#10'C = ' + IntToStr(i));



  X := MatchStringAll('*F1*F2*~a~a~a', S, []);
  If X <> nil Then Begin
    Sr := '';
    For i := 0 to Length(X) div 3 - 1 do
      Sr := Sr + 'Sr[' + IntToStr(i) + '] = "' + X[i * 3 + 1] + '"'#13#10
  End Else Sr := 'nichts gefunden';

  ShowMessage('4:'#13#10 + Sr);



  X := MatchStringAll('*V{13}*', S, []);
  If X <> nil Then Begin
    Sr := '';
    For i := 0 to Length(X) div 3 - 1 do
      Sr := Sr + 'Sr[' + IntToStr(i) + '] = "' + X[i * 3 + 1] + '"'#13#10
  End Else Sr := 'nichts gefunden';

  ShowMessage('5:'#13#10 + Sr);


  X := MatchStringAll('*V{13}*', S, [cfIgnoreOuterAsterix]);
  If X <> nil Then Begin
    Sr := '';
    For i := 0 to High(X) do
      Sr := Sr + 'Sr[' + IntToStr(i) + '] = "' + X[i] + '"'#13#10
  End Else Sr := 'nichts gefunden';

  ShowMessage('6:'#13#10 + Sr);
theoretisch müßte auch sowas möglich sein (hab's jetzt nicht geteste)
X := MatchStringAll('*<img *src="*"*', S, [cfNotCaseSensitive, cfIgnoreOuterAsterix]); da müßten nun abwechseln (evt. vorhandene) weitere Parameter und die URL in X drinstehn ... denk ich mal

Download siehe #26
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von GPRSNerd
GPRSNerd

Registriert seit: 30. Dez 2004
Ort: Ruhrpott
239 Beiträge
 
Delphi 10.4 Sydney
 
#33

Re: Stringvergleich mit Wildcards

  Alt 22. Jun 2009, 21:30
Hi,

besser, aber immer noch nicht auf dem guten Stand vor deinen Änderungen!

Folgende Tests schlagen immer noch fehl, größtenteils im zusammenhang mit Escaping:

Delphi-Quellcode:
Assert(MatchText('te\*23', 'te023')=false);
Assert(MatchText('te\?23', 'te023')=false);
Assert(MatchText('te\|23', 'te023')=false);
Assert(MatchText('te\\23', 'te023')=false);

Assert(MatchText('a*d|a*', 'abcdef')=True);
Du näherst dich wieder dem Ziel...
Stefan
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#34

Re: Stringvergleich mit Wildcards

  Alt 22. Jun 2009, 22:16
Bezüglich des Escaping:
Delphi-Quellcode:
'\': If not (cfOnlyWild in Flags) and (Mp + 1 < Me2) Then
       Case (Mp + 1)^ of '*', '?', '{', '~', '|', '\': Inc(Mp); End
     Else GoTo LElse;
kleiner Unterschied, große Wirkung
Delphi-Quellcode:
'\': Begin
       If not (cfOnlyWild in Flags) and (Mp + 1 < Me2) Then
         Case (Mp + 1)^ of '*', '?', '{', '~', '|', '\': Inc(Mp); End;
       GoTo LElse;
     End;
und das Andere ... eine kleine Variable übersehn
(neues MaskenEnde Me in '|' nicht gesetzt)


Download siehe #26
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von GPRSNerd
GPRSNerd

Registriert seit: 30. Dez 2004
Ort: Ruhrpott
239 Beiträge
 
Delphi 10.4 Sydney
 
#35

Re: Stringvergleich mit Wildcards

  Alt 22. Jun 2009, 23:12
Jau, jetzt geht wieder alles.
Da sieht man wie wichtig Unittests sind bei so komplexen Funktionen! (benutze ich aber auch noch nicht so lange ).

Danke für deinen Code (und deine Geduld mit meinen Nörgeleien )!
Stefan
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#36

Re: Stringvergleich mit Wildcards

  Alt 23. Jun 2009, 16:24
Achtung: diese Veränderung bewirkt nur eine Verbesserung bei UnicodeStrings (PWideChar, WideString und UnicodeString)

Eigentlich hatte ich sowas zwar nicht vor, aber ich hab mich doch mal entschlossen die Unicodebehandlung aus meinem himXML zu extrahieren und hier mit einzubauen.

Es wird beim Unit-Start ein kleines Abbild des gesamten Unicode-2-Zeichensatzes angelegt und dann direkt darüber verglichen.

Nun wird also keine "LowerCase"-Kopie des Strings mehr benötigt, wenn nicht CaseSensitiv verglichen wird.
Und auch nicht mehr, wenn ein | im Suchmuster vorkommt.

Es gibt also vorallem bei langen Strings Vorteile, da nichts mehr rumkopiert werden muß.

Alleine nachfolgender Code ist damit gleich so etwa 3 mal schneller, als mit der alten Version:

Allerdings ist diese Version nicht zur Geschwindigkeitsoptimierung gedacht,
(im Durchschnitt mag sich dieses nur minimal ändern und vorallam nicht bei CaseSensitivem Vergleich)
sondern der Speicheroptimierung (kein unnötiges Rumhantieren im Speichermanager)

Außerdem gibt es noch ein paar zusätzliche Funktionen
* WideLowerCase > sollte klar sein
* WideSameText > das auch
* und eine abgewandelte Version von Hagen's ELF-Hash, welcher auf Unicode erweitert wurde und auch noch die Maskenzeichen beachtet

Delphi-Quellcode:
Var T: LongWord;

T := GetTickCount;
For i := 1 to 100000 do Begin
  MatchText('', 'abcdef');
  MatchText('abc', '');
  MatchText('abcdef', 'abcdef');
  MatchText('df', 'abcdef');
  MatchText('abc', 'abcdef');
  MatchText('def', 'abcdef');
  MatchText('abc?f', 'abcdef');
  MatchText('abc??f', 'abcdef');
  MatchText('abc*f', 'abcdef');
  MatchText('a?def', 'abcdef');
  MatchText('a??def', 'abcdef');
  MatchText('a*def', 'abcdef');
  MatchText('abcd?', 'abcdef');
  MatchText('abcd??', 'abcdef');
  MatchText('abcd???', 'abcdef');
  MatchText('abcd*', 'abcdef');
  MatchText('a?def', 'abcdef');
  MatchText('a??def', 'abcdef');
  MatchText('a*def', 'abcdef');
  MatchText('?cdef', 'abcdef');
  MatchText('??cdef', 'abcdef');
  MatchText('*cdef', 'abcdef');
  MatchText('b*c*f', 'abcdef');
  MatchText('a*c*f', 'abcdef');
  MatchText('a?c*f', 'abcdef');
  MatchText('a?d*f', 'abcdef');
  MatchText('*a*f*', 'abcdef');
  MatchText('*a?bf*', 'abcdef');
  MatchText('*c*f*', 'abcdef');
  MatchText('*c*d*', 'abcdef');
  MatchText('*c?f*', 'abcdef');
  MatchText('*d?f*', 'abcdef');
  MatchText('*', '');
  MatchText('*', 'abcdef');
  MatchText('a*', 'abcdef');
  MatchText('*f', 'abcdef');

  MatchText('ab\*ef', 'abcdef');
  MatchText('ab\*ef', 'ab*ef');
  MatchText('ab\*ef', 'abcef');

  MatchText('a*d|a*', 'abcdef');
  MatchText('a*d|a*', 'abcdef');
  MatchText('a*d|z*', 'abcdef');
End;
T := GetTickCount - T;
ShowMessage(IntToStr(T));
und wo ich den Code einzeln hab, kann ich nun auch mal in Ruhe (einfacher) schauen, ob mit der LowerCase-Behandlung auch alles richtig läuft ... mal sehn ob auch alles wirklich stimmt
Angehängte Dateien
Dateityp: pas matchtextunit_153.pas (88,7 KB, 125x aufgerufen)
Dateityp: exe project1_143.exe (565,5 KB, 17x aufgerufen)
Dateityp: exe project1_202.exe (558,0 KB, 21x aufgerufen)
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von GPRSNerd
GPRSNerd

Registriert seit: 30. Dez 2004
Ort: Ruhrpott
239 Beiträge
 
Delphi 10.4 Sydney
 
#37

Re: Stringvergleich mit Wildcards

  Alt 23. Jun 2009, 20:54
Funktioniert noch alles

Ich werde in den nächsten Tagen mal ein paar Unittests für die unterschiedlichen String-Varianten, insbesondere Unicode, bauen und die Ergebnisse posten.

Cheers!
Stefan
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#38

Re: Stringvergleich mit Wildcards

  Alt 26. Jul 2009, 10:51
gibt jetzt keine großartigen Veränderungen ... ich hab nur den UTF8String hinzugefügt.

theoretisch/praktisch wird dort genauso verglichen, wie beim AnsiString, aber der Compiler nörgelt etwas rum, wenn man einen UTF8String an einen AnsiString übergeben möchte.
Drum hab ich einfach die Versionen mit AnsiString geklont und auf UTF8String (siehe System.pas) umgestellt.

[edit 11.02.2010]
Anhang entfernt > aktuelle Version siehe Beitrag #36
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#39

Re: Stringvergleich mit Wildcards

  Alt 1. Nov 2009, 11:10
Und noch 'ne kleine Anpassung bezüglich "älteren" Delphis.

Mein D7 mochte verständlicher Weise das {$STRINGCHECKS OFF} nicht, welches Letztens mir reinrutschte.
Darum würde dieses etwas verschoben, bzw. von Delphi < 2009 versteckt.

[edit 11.02.2010]
Anhang entfernt > aktuelle Version siehe Beitrag #36
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von DelphiBandit
DelphiBandit

Registriert seit: 19. Feb 2007
Ort: In der Lüneburger Heide
165 Beiträge
 
Delphi 10.4 Sydney
 
#40

Re: Stringvergleich mit Wildcards

  Alt 11. Feb 2010, 11:35
Zitat von himitsu:
gibt jetzt keine großartigen Veränderungen ... ich hab nur den UTF8String hinzugefügt.
ich habe gerade mal versucht die letzte Version der Unit einzubauen und zu benutzen. Leider werde ich mit Fehlermeldungen "MatchStringEx" "Doppeldeutig überladene Version von..." zugebomt (RS 2007, also ohne UniCode). Nehme ich die Version 1.2 ohne UTF8 lässt es sich durchkompilieren.

Gibt es dafür einen Compilerschalter, damit er auch die UTF8-Version durchkompilieren kann? Oder hat einer von Euch eine andere Idee warum das nicht funktioniert?
Carsten
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 4 von 5   « Erste     234 5      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:11 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