7 Stimmen

Wie funktionieren die Bedingungen in Umgehungsgruppen in .NET Regex?

Beim Herumspielen mit regulären Ausdrücken, insbesondere dem ausgewogenen Abgleich der .NET-Variante, kam ich an einen Punkt, an dem mir klar wurde, dass ich das Innenleben der Engine nicht so gut verstehe, wie ich dachte. Ich würde mich über jeden Beitrag dazu freuen, warum sich meine Muster so verhalten, wie sie es tun! Aber fist...

Haftungsausschluss: Diese Frage ist rein theoretisch, und alle hier erzielten Ergebnisse werden niemals verwendet oder verändert und in Produktionscode zum Parsen von HTML eingesetzt. Niemals. Das verspreche ich. Ich habe Angst vor dem Pony =)

Nun zu meinem Problem. Ich werde versuchen, den Buchstaben zuzuordnen A wenn ihm nicht eine der folgenden Angaben vorausgeht # . Zur Veranschaulichung verwende ich immer die Zeichenfolge ..A..#..A.. . Hier ist die erste A angepasst werden sollte. Natürlich ist dies eine recht einfache Aufgabe, indem man "A(?<!^.*#.*)" aber ich möchte hier Konditionale verwenden, da sie für ausgewogene Übereinstimmungen und andere coole Dinge verwendet werden können.

Was ich versucht habe, ist

"A(?<=^(#(?<q>)|[^#])*(?(q)(?!)))"

Ich interpretiere es so: Wenn die Maschine auf ein "A" stößt, geht sie zum Anfang der Zeichenkette zurück und fügt für jedes Zeichen eine leere Übereinstimmung zur Erfassungsgruppe q hinzu, wenn das Zeichen ein # ist. Dann sollte es fehlschlagen, wenn q eine Übereinstimmung enthält. Was ich nicht verstehe, ist, warum dieser Ausdruck auf beide "As" in meiner Beispielzeichenkette passt.

Wenn ich einfach das Lookbehind entferne und die gesamte Zeichenfolge abgleiche, funktioniert dies:

"^(#(?<q>)|[^#])*(?(q)(?!))A"

passt auf die gesamte Zeichenkette bis zum ersten A, auch wenn der Quantifizierer der ersten Gruppe gierig ist. Das Einfügen eines '#' am Anfang führt ebenfalls dazu, dass die Übereinstimmung fehlschlägt (wie gewünscht).

Wie spielen also "look around"-Gruppen, "named capturing"-Gruppen in ihnen und Konditionale zusammen?

Danke!

Bearbeiten: Dieses Problem lässt sich leichter erkennen in (?<=(?<q>)(?(q)(?!))). , das auf kein Zeichen passen sollte, aber auf alles passt.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X