Probleme durch gieriges Verhalten
(Auszug aus "Reguläre Ausdrücke" von Jeffrey E. F. Friedl)
Im letzten Beispiel haben wir gesehen, dass ˹.*˼ zunächst immer bis an das Zeilenende (Bei Werkzeugen, bei denen der Punkt auch auf das Newline passt, geht es bis an das Ende des Strings, auch wenn der String mehrere logische Zeilen enthält.) durchmarschiert. Das liegt daran, dass ˹.*˼ nur an sich selbst denkt und alles zusammenrafft, was es kriegen kann; zurück gibt es nur, wenn ein späteres Element der Regex etwas braucht, damit die Regex als Ganzes erfolgreich passt.
Manchmal kann das ernsthaft mühsam sein. Betrachten wir eine Regex, die Text finden soll, der in Gänsefüßchen ist. Zunächst würde man etwas wie ˹".*"˼ schreiben, aber raten Sie mal (mit Blick darauf, was wir über ˹.*˼ wissen), was bei einem String wie diesem herauskommt:
Der Name "McDonald's" wird japanisch "makudonarudo" ausgesprochen
Sie müssen gar nicht raten, Sie wissen genug über den Mechanismus der Mustererkennung. Nachdem das erste Anführungszeichen erkannt worden ist, wird das ˹.*˼ auf alle Zeichen bis zum Ende des Strings passen. Beim folgenden Backtracking wird es nur so weit zurückgehen, oder besser gesagt: Es wird von der Maschine so weit zurückgedrängt, wie es für einen Treffer der ganzen Regex erforderlich ist – bis zum letzten Anführungszeichen. Somit wird der Ausdruck auf
Der Name "McDonald's" wird japanisch "makudonarudo" ausgesprochen
passen, was kaum der String in Anführungszeichen ist, der gemeint war. Dies ist einer der Gründe, warum ich vor zu häufigem Gebrauch von ˹.*˼ warne; er führt manchmal zu unvorhergesehenen Resultaten.
Nun, wie macht man’s, dass nur "McDonald's" gefunden wird? Eigentlich wollen wir nicht »irgendetwas« zwischen den Anführungszeichen, sondern »irgendetwas außer einem Anführungszeichen«. Wenn wir ˹[^"]*˼ statt ˹.*˼ benutzen, wird nicht über das Ziel hinausgeschossen.
Die grundlegende Verhaltensweise der Regex-Maschine ist mit ˹"[^"]*"˼ genau die gleiche wie zuvor. Wenn das erste Anführungszeichen gefunden ist, erhält ˹[^"]*˼ die Möglichkeit, auf so viele Zeichen zu passen, wie es ihm beliebt. In diesem Fall gilt das bis zu dem Anführungszeichen hinter McDonald's, ˹[^"]˼ passt nicht mehr auf dieses Anführungszeichen. Die Maschine übergibt die Kontrolle dem dritten Element, dem abschließenden Anführungszeichen in der Regex, das genau auf das Anführungszeichen im String passt. Das Resultat stimmt nun:
Der Name "McDonald's" wird japanisch "makudonarudo" ausgesprochen
Es könnte unter Umständen noch einen nicht eingeplanten Unterschied geben; in den meisten Dialekten passt ˹[^"]˼ im Gegensatz zum Punkt auf ein Newline. Wenn Sie nicht wollen, dass sich der Treffer auf mehrere Zeilen verteilt, verwenden Sie ˹[^"\n]˼.
<< zurück | vor >> |
Tipp der data2type-Redaktion: Zum Thema Reguläre Ausdrücke bieten wir auch folgende Schulungen zur Vertiefung und professionellen Fortbildung an: |
Copyright der deutschen Ausgabe © 2008 by O’Reilly Verlag GmbH & Co. KG
Für Ihren privaten Gebrauch dürfen Sie die Online-Version ausdrucken.
Ansonsten unterliegt dieses Kapitel aus dem Buch "Reguläre Ausdrücke" denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.
O’Reilly Verlag GmbH & Co. KG, Balthasarstr. 81, 50670 Köln