Code:
...
re.RegEx := '({4:\r\n(?:[^\r\n]*\r\n)*-})';
Hallo,
ich habe mit meinen RegEx Experten gesprochen.
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:
...
re.RegEx := '(\{4\:.*?-\})';
...
'{4: bla bla bla bla -}{4: bla bla -}'
-> '{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
![Wink](images/smilies/icon_wink.gif)
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:
...
// 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\:.*?-\})';
...
Habe ich ausprobiert funktioniert.
![Stupid](images/smilies/stupid.gif)
[/edit]
[edit] Beispiel:
Delphi-Quellcode:
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.
[/edit]