Reguläre Ausdrücke – regex, singleline, non-greedy

Ich habe mich bisher nur so viel wie nötig mit regulären Ausdrücken beschäftigt. Der komplexe Syntax und das kryptische Aussehen der regulären Ausdrücke haben mich bisher davon abgeschreckt, reguläre Ausdrücke zu benutzen. Kürzlich hatte ich aber das Problem, in vb.net Text zwischen einer Startmarkierung und einer Endmarkierung zu suchen. Natürlich kann man das auch mit den .net Stringfunktionen erreichen, aber ich wollte es dieses Mal mit regulären Ausdrücken versuchen.

Nach einigen Anfangsproblemen bin ich nun richtig begeistert von der Mächtigkeit der regulären Ausdrücke.

Mein erstes Problem war, dass sich mein zu analysierender Text über mehrere Zeilen zog, also waren Zeilenumbrüche vorhanden. Ebenso zogen sich die zu extrahierenden Textstellen über mehrere Zeilen. Meine regulären Ausdrücke lieferten nicht das erwartete Ergebnis. Besser gesagt: Sie lieferten gar kein Ergebnis.

Nach etwas Internetrecherche erfuhr ich, dass bei der Erstellung eines regex Objektes Optionen angegeben werden können. In vb.net findet sich das Ganze unter: System.Text.RegularExpressions.RegexOptions

Ohne weiter nachzulesen, wählte ich die Option Multiline, da ich ja Text zeilenübergreifend analysieren wollte. Diese Option lieferte aber zu meiner Überraschung ebenfalls kein Ergebnis.

Also machte ich mich daran, die Optionen näher anzuschauen. Dabei fand ich eine weitere Option: Singleline. Und genau diese muss man angeben, um das gewünschte Ergebnis zu erreichen. Ich finde das Ganze zwar etwas verwirrend: Singleline für zeilenübergreifendes Analysieren – aber Hauptsache, es funktioniert.

Wenn man also Text in vb.net mit regulären Ausdrücken über mehrere Zeilen hinweg analysieren möchte, muss man folgende Option einstellen:

System.Text.RegularExpressions.RegexOptions.Singleline

Beispiel:

Text, der analysiert werden soll:

start text1
text2
text3 ende

Regulärer Ausdruck: start(.*)ende

Dieser Ausdruck soll einen String zwischen start und ende extrahieren.

Ergebnis ohne die Option Singleline:

– Es wird nichts gefunden

Ergebnis mit der Option Singleline:

text1
text2
text3

Danach tauchte aber ein weiteres Problem auf. Bei sich mehrfach wiederholenden Mustern im Text, wurde immer die größtmögliche Ergebnismenge zurückgeliefert. Ich brauchte aber jede einzelne Ergebnismenge. Das Ganze wird an einem Beispiel deutlicher:

Text, der analysiert werden soll:

start text1
text2
text3 ende
start text4
text5
text6 ende

Der Regulärer Ausdruck: start(.*)ende liefert folgendes Ergebnis:

text1
text2
text3 ende
start text4
text5
text6

Gewünscht waren aber 2 Ergebnismengen:

Ergebnis 1:

text1
text2
text3

Ergebnis 2:

text4
text5
text6

Bei der Lösung dieses Problems stieß ich auf die Begriffe greedy (gierig) und non-greedy (nicht gierig) im Zusammenhang mit der Definition von regulären Ausdrücken. Greedy bedeutet, es wird immer die größtmögliche Ergebnismenge zurückgeliefert und non-greedy bedeutet, es wird die kleinstmögliche Ergebnismenge zurückgeliefert. Standartmäßig zeigen reguläre Ausdrücke ein “gieriges (greedy)” Verhalten. Um ein “nicht gieriges (non-greedy)” Verhalten zu erreichen, muss man bei der Definition von regulären Ausdrücken nach dem Quanifizierer noch ein ? anfügen.

Beispiel:

Text, der analysiert werden soll:

start text1
text2
text3 ende
start text4
text5
text6 ende

Der reguläre Ausdruck: start(.*?)ende liefert das gewünschte Ergebnis:

Ergebnis 1:

text1
text2
text3

Ergebnis 2:

text4
text5
text6

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert