AW: TPerlRegEx - stack overflow
Ja, gutes Näschen. :wink:
Es folgt am Anfang der letzten Zeile immer ein '-}' Eine Swiftnachricht besteht aus mehreren Blöcken.
Code:
Der Block 4 (Textblock) muss immer mit '{4:'+Zeilenumbruch anfangen und mit Zeilenumbruch+'-}' enden.
{1:...}{2:...}{3:...}{4:
Nachrichteinhalt -}{5:} Blöcke 1+2 enthalten Adressinformationen (Absender+Empfänger), 3 Userinfos und 5 Checksummen und son Zeuchs. 1+3+5 sind optional. Ich habe eben auch noch einen anderen funktionierenden Konstrukt gebastelt
Code:
{4:\R(?:[[:ascii:]]+\R)+-}
|
AW: TPerlRegEx - stack overflow
So. Nach einigen Tests habe ich mich für die non-greedy Variante entschieden.
Performance liegt bei etwa 22000 Nachrichten/h, also parsen, zerlegen und strukturiert in der DB ablegen. Auf den produktiven Systeme geht das noch ne ganze Ecke flotter. Ist zwar langsamer als vorher, jedoch vollkommen zufriedenstellend. :-D Nun lass ich die Bibliothek auf die anderen Prozesse los. Dank Euch bis hierhin für die Hilfe. :thumb: @ele Bin sehr zufrieden mit meinem Arbeitgeber. Aber vielleicht kann man sich ja auf fachlicher Ebene ein wenig austauschen. Bei mir steht beispielweise demnächst die Erweiterung auf ISO20022 (XML) an. |
AW: TPerlRegEx - stack overflow
Zitat:
ich habe mit meinen RegEx Experten gesprochen. 8-) Er sagt, Deine RegEx sieht so aus, als hättest Du den Unterschied zwischen greedy und non-greedy nicht richtig verstanden, als Du diese Expression erstellt hast. Es sieht so aus, als wolltest Du das non-greedy manuell erzwingen. Das macht die RegEx nur unnötig kompliziert. Folgende Expression würde alles zwischen dem '{4:' und '-}' auswählen. Mit der non-greedy Option '?' die nach dem Wildcard '*' steht, wird das Ergebnis möglichst kurz gehalten.
Code:
'{4: bla bla bla bla -}{4: bla bla -}'
...
re.RegEx := '(\{4\:.*?-\})'; ... -> '{4: bla bla bla bla -}' wird ausgewählt
Code:
...
re.RegEx := '(\{4\:.*-\})'; // ohne ? -> greedy ... ohne ? -> greedy wird folgendes ausgewählt: '{4: bla bla bla bla -}{4: bla bla -}' Durch die Vereinfachung der RegEx ist es nicht nur einfacher zu lesen sondern es werden auch weniger rekursive Aufrufe nötig, also auch der Stack weniger beansprucht ;-) Ich hoffe das hilft Dir weiter. cu MaBuSE [edit] Obiges Beispiel funktioniert natürlich nur wenn die SingleLine Option aktiv ist. Nur dann steht der '.' auch für ein '/n'.
Delphi-Quellcode:
Habe ich ausprobiert funktioniert. :stupid:
...
// re.Options := [preCaseLess, preSingleLine]; // re.RegEx := '(\{4\:.*?-\})'; // alternativ kann man die Optionen auch in die RegEx schreiben: // '?' -> jetzt kommen Optionen -> 's' = SingleLine ; 'i' = CaseLess -> ':' = Optionen Ende re.Options := []; re.RegEx := '(?si:\{4\:.*?-\})'; ... [/edit] [edit] Beispiel:
Delphi-Quellcode:
[/edit]
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Memo1: TMemo; procedure Button1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation uses RegularExpressionsCore; {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var re : TPerlRegEx; teststr : UTF8String; l1 : integer; begin try re := TPerlRegEx.create; re.State := []; re.Options := []; re.RegEx := '(?si:\{4\:.*?-\})'; re.Compile; // Nun Beispielstring mit Inhalt // {4: // :00X:ABCDEFB0123456789 // :00X:ABCDEFB0123456789 // -} // ... // {4: // :00X:ABCDEFB0123456789 // :00X:ABCDEFB0123456789 // -} // zusammenbauen TestStr := '{4:'+chr(13)+chr(10); for l1 := 1 to 2 do begin TestStr := TestStr + ':00X:ABCDEFB0123456789' +chr(13)+chr(10); end; TestStr := TestStr + '-}'; TestStr := TestStr + TestStr + TestStr + TestStr; re.Subject := TestStr; if re.Match then begin Memo1.Lines.Add(re.MatchedText); Memo1.Lines.Add('-------------------'); while re.MatchAgain do begin Memo1.Lines.Add(re.MatchedText); Memo1.Lines.Add('-------------------'); end; end else begin Memo1.Lines.Add('Kein Treffer') end; except on E: Exception do Memo1.Lines.Add(E.ClassName+ ': '+ E.Message); end; end; end. |
AW: TPerlRegEx - stack overflow
Wow. Danke fur die ausführliche Untersuchung.:)
Ich möchte, dass sich das nur matcht, wenn die unter #11 beschriebenen Kriterien zutreffen. Also nach {4: ein Umbruch, danach Zeilen mit Egal plus Umbruch und danach eine letzte Zeile mit einem -} am Anfang. So ganz habe ich aber in der Tat den Zusammenhang mit dem Stack noch nicht ergründen können. |
AW: TPerlRegEx - stack overflow
Zitat:
Zitat:
Delphi-Quellcode:
re.RegEx := '(\{4\:/n.*?/n-\})';
Zitat:
Parameter von Prozeduren und Funktionen werden auf dem Stack gespeichertund nach dem Ende der Funktion wieder freigegeben. Bei einer Rekursion ruft sich eine Funktion selbst auf. Wenn eine Funktion sich z.B. 100 mal aufruft, dann wird auch 100 mal Stack für Parameter benötigt. Ich hoffe das hilft Dir weiter. |
AW: TPerlRegEx - stack overflow
Nene. Stack und Heap, hab ich lieb. Damit kenne ich mich schon aus. 8-)
Nur den Zusammenhang zwischen greedy und lazy im Zusammenhang mit dem PCRE-Stack hab ich nicht verstanden. Hier ein glaube ich altes Beispiel. banane b(an)+ liefert 'banan' b(an)+? liefert der Faulheit wegen nur noch 'ban' Hänge ich dem Ausdruck ein e an b(an)+?e liefert das 'banane'. Er ackert also den Match mit (an)+? zwei Mal durch. Genauso verhält es sich mit meinem Ausdruck ganz oben. Nur statt 'an' eben einzelne Zeilen mit einem Umbruch am Ende. Wieso liefert greedy einen stack overflow und lazy keinen. Die X Zeilen muss er in beiden Fällen durchlaufen. Meinste statt /n vielleicht nicht eher \n ? :) Statt \n nehme ich \r\n, also einen Windows-Umbruch #13#10. |
AW: TPerlRegEx - stack overflow
Zitat:
In Deiner XE Ent. Version sind ja alle Quelltexte enthalten. IN Projektoptionen Debug-DCUs anschalten und einfach mal in die Match Methode reindebuggen ;-) Zitat:
|
AW: TPerlRegEx - stack overflow
Zitat:
|
AW: TPerlRegEx - stack overflow
Zitat:
Zitat:
Das debuggen von PCRE willst du dir nicht antun - selbst wenn der code in Delphi geschreiben wäre. Regular Expression Engines sind ein ziemlich komplizierte Dinger und die PCRE ist ein Monster. Da schreibst du lieber deinen eigenen Parser - das benötigt weniger Zeit. |
AW: TPerlRegEx - stack overflow
Zitat:
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:50 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