Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi TRegExpr (https://www.delphipraxis.net/190649-delphi-tregexpr.html)

Jim Carrey 22. Okt 2016 13:04

Delphi TRegExpr
 
Ich tue mich gerade ein bisschen schwer mit diesem Neuland namens RegExpr.

Ich benutze eine simple String-Funktion, um die Vorkommen eines Strings TeilString in einem String S zu zählen.
Ich möchte das gerne auf RegEx umstellen, sodass ich auch Wildcards im TeilString benutzen darf.

Nur wie?

Delphi-Quellcode:
RegExpr := TRegExpr.Create;
try
 RegExpr.ModifierG := False;
 RegExpr.Expression := '<!-- DIESEN * MÖCHTE ICH FINDEN -->'; // * könnte alles sein, daher ist Pos() keine Lösung
 // un nu?
finally
 RegExpr.Free;
end;

himitsu 22. Okt 2016 13:14

AW: Delphi TRegExpr
 
Ähhhhh, nimm einen HTML-Parser und schon ist alles Richtig. :roll:

Und ich glaube du hast RegEx noch nicht ganz verstanden.
"*" ist kein Platzhalter, wie z.B. ? und * bei der Dateisuche.
Das ist ein Multiolikator, der auf das Zeichen davor angewendet wird, also suchst du nach 0 oder mehreren Leerzeichen.

Zitat:

// un nu?
Man mag es nicht glauben, aber das wird in jedem TRegExpr-Turorial gezeigt und davon kennen die SuFu und Google massenaft.
Sogar die OH zeigt wie es geht, bzw. sie verlinkt auf die entsprechende Demo.


Und doch, auch Pos/PosEx wäre eine Lösung, denn man kann ja das davor und das danach suchen und dann das dazwischen rauskopieren. :angle:

Jim Carrey 22. Okt 2016 13:16

AW: Delphi TRegExpr
 
Ginge das hier auch oder ist das Quatsch?
Delphi-Quellcode:
TRegEx.Matches(sMeinString, '<!-- DIESEN (.*) MÖCHTE ICH FINDEN -->').Count

himitsu 22. Okt 2016 13:29

AW: Delphi TRegExpr
 
Zitat:

Zitat von Jim Carrey (Beitrag 1351724)
Ginge das hier auch oder ist das Quatsch?

Mal sehn was Delphi-Referenz durchsuchenTMatchCollection.Count sagt ... joar?

ABER, denk dir eine ( ) um Alles drumrum und wenn es was trifft, dann hast du somit je ZWEI Matches pro Match, da 2 (...) ,
aber im Notfall einfach ausprobieren. :zwinker:
docwiki.embarcadero.com/RADStudio/Seattle/en/Regular_Expressions
docwiki.embarcadero.com/CodeExamples/Seattle/en/RTL.RegExpressionVCL_Sample
docwiki.embarcadero.com/Libraries/Seattle/en/System.RegularExpressions.TRegEx.Matches <- "Returns all the matches present in the input string"
docwiki.embarcadero.com/Libraries/Seattle/en/System.RegularExpressions.TMatchCollection

Jim Carrey 22. Okt 2016 13:30

AW: Delphi TRegExpr
 
Danke für die Literatur. Somit verwende ich jetzt Matches statt Match, da ich das besser in meiner Schleife gebrauchen kann.
Jetzt muss ich nur noch finden, wie man die einzelnen Funde ausließt.

Jim Carrey 22. Okt 2016 15:26

AW: Delphi TRegExpr
 
Ok ich habe jetzt alles hinbekommen.
Nur ist RegEx hier ein bisschen... sehr lahmarschig wie ich finde. Bei einer 5 MB großen Datei dauern 2 TRegEx.Matches-Ausführungen mit jeweils 2x (.*) (also 4 insgesamt) im Pattern insgesamt 24 Sekunden - vorher mit einer sehr umständlichen pos/posex-Konstruktion 5 Sekunden.

jfheins 22. Okt 2016 15:39

AW: Delphi TRegExpr
 
Es hilft, wenn der Regex nicht greedy ist. Denn so wird erstmal der komplette Dateiinhalt für das erste .* gematcht, dann merkt die Engine, dass das nicht passt und probiert es ein Zeichen früher aus. Es hilft dann auch schon viel, wenn du nicht "." nimmst, sondern nur bestimmte Zeichen zulässt.

Jim Carrey 22. Okt 2016 15:40

AW: Delphi TRegExpr
 
Dieses Wort höre ich zum ersten mal. Wo stelle ich das denn ein ob es greedy ist oder nicht?
Warte ich bin dumm ich habs. Es dauert aber genau solange.

(.*?) statt (.*) meinst du doch?

SProske 22. Okt 2016 16:40

AW: Delphi TRegExpr
 
Egal ob .* oder .*?, wenn es dir um Performance geht, sollte man beide eigentlich vermeiden. Du wirst aber selbst mit einem hoch-optimierten Regex kaum eine Chance gegen Pos/Posex-Suche haben.

Solltest du also tatsächlich nach
Code:
<!-- DIESEN (.*) MÖCHTE ICH FINDEN -->
suchen, ginge evt. noch so etwas wie:
Code:
<!-- DIESEN ((?>[^ \n\r]+| (?!MÖCHTE ICH FINDEN -->))*) MÖCHTE ICH FINDEN -->
Solltest du hingegen nach
Code:
<!--(.*)-->
suchen (was mir sinnvoller erschiene), ginge dann
Code:
<!--((?>[^-\r\n]+|-(?!->))*)-->

Jim Carrey 22. Okt 2016 17:23

AW: Delphi TRegExpr
 
Ich hätte noch eine weitere Idee.
Genau genommen geht es hier um Log-Dateien und deren Einträge, welche ich pro-Datum anzeigen lassen möchte.
Also iteriere ich durch die Log-Datei und gucke, ob dieser Eintrag-N zu Datum X passt.
Dafür suche ich mir per RegEx aktuell eben nur die erste und letzte Zeile jedes Log-Eintrags raus.
Die beginnen eben mit <!-- loganfang datum --> und endet mit <!-- logende datum -->
Dann kopiere ich von loganfang bis logende und so bekomme ich alle Logeinträge für Datum X.

Das Zusammenschnippseln geht schnell (< 60ms). Aber das RegEx dauert bei 5 MB und einer Testdatei mit, ich glaube es waren rund 9000 Zeilen mit loganfang und logende eben rund 25 Sekunden.

Jetzt zu meiner Idee.
ich speichere einfach 1 Logdatei pro Tag. Dann brauche ich nur die Datei einzulesen und bin von diesem RegEx komplett weg.


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:54 Uhr.
Seite 1 von 2  1 2      

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