![]() |
Re: Stringvergleich mit Wildcards
menno ... ich schau mal
eigentlich dachte ich, diesbezüglich hätt ich nichts verändert :oops: 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 :nerd: |
Re: Stringvergleich mit Wildcards
das ist eigentlich zu peinlich zum Erwähnen: :oops:
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 :wall: 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 :-D
Delphi-Quellcode:
theoretisch müßte auch sowas möglich sein (hab's jetzt nicht geteste)
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);
Delphi-Quellcode:
da müßten nun abwechseln (evt. vorhandene) weitere Parameter und die URL in X drinstehn ... denk ich mal :gruebel:
X := MatchStringAll('*<img *src="*"*', S, [cfNotCaseSensitive, cfIgnoreOuterAsterix]);
![]() |
Re: Stringvergleich mit Wildcards
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:
Du näherst dich wieder dem Ziel...
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); |
Re: Stringvergleich mit Wildcards
Bezüglich des Escaping:
Delphi-Quellcode:
kleiner Unterschied, große Wirkung :freak:
'\': If not (cfOnlyWild in Flags) and (Mp + 1 < Me2) Then
Case (Mp + 1)^ of '*', '?', '{', '~', '|', '\': Inc(Mp); End Else GoTo LElse;
Delphi-Quellcode:
und das Andere ... eine kleine Variable übersehn
'\': Begin
If not (cfOnlyWild in Flags) and (Mp + 1 < Me2) Then Case (Mp + 1)^ of '*', '?', '{', '~', '|', '\': Inc(Mp); End; GoTo LElse; End; (neues MaskenEnde Me in '|' nicht gesetzt) ![]() |
Re: Stringvergleich mit Wildcards
Jau, jetzt geht wieder alles. :thumb:
Da sieht man wie wichtig Unittests sind bei so komplexen Funktionen! (benutze ich aber auch noch nicht so lange :angel2: ). Danke für deinen Code (und deine Geduld mit meinen Nörgeleien :wink: )! |
Re: Stringvergleich mit Wildcards
Liste der Anhänge anzeigen (Anzahl: 3)
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ß. :stupid: 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:
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 :angel:
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)); |
Re: Stringvergleich mit Wildcards
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! |
Re: Stringvergleich mit Wildcards
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. :angel: [edit 11.02.2010] Anhang entfernt > aktuelle Version siehe Beitrag #36 |
Re: Stringvergleich mit Wildcards
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 |
Re: Stringvergleich mit Wildcards
Zitat:
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? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:22 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