Kurzer Überblick
(Auszug aus "Reguläre Ausdrücke" von Jeffrey E. F. Friedl)
Die folgende Tabelle mit ein paar Eigenschaften einiger vielbenutzter Programme vermittelt einen Eindruck davon, wie verschieden die Dialekte geworden sind. Diese Tabelle ist nur summarisch, sie gibt nur einen oberflächlichen Eindruck von bestimmten Aspekten einiger Regex-Dialekte.
Diese Art von Tabelle findet man oft in Büchern, um die Unterschiede zwischen den verschiedenen Programmen zu illustrieren. Aber sie zeigt nur die Spitze des Eisbergs – zu jedem angegebenen Feature gibt es ein Dutzend feine, aber wichtige Punkte, die nicht dargestellt sind.
Tabelle: Summarischer Überblick über die Regex-Dialekte einiger Programme.
Feature | Modernes grep | Modernes egrep | Emacs | Tcl | Perl | .NET | Suns Java-Package |
---|---|---|---|---|---|---|---|
*, ^, $, [...] | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
? + | | \? \+ \| | ? + | | ? + \| | ? + | | ? + | | ? + | | ? + | |
Gruppieren | \(...\) | (...) | \(...\) | (...) | (...) | (...) | (...) |
(?:...) | ✓ | ✓ | ✓ | ||||
Wortgrenzen | \<, \> | \<\>, \b\B | \m, \M, \y | \b, \B | \b, \B | \b, \B | |
\w , \W | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | |
Rückwärtsreferenzen | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
(✓: unterstützt) |
Als Erstes muss man sich vergegenwärtigen, dass die meisten Programme ständig weiterentwickelt werden. Tcl kannte früher keine Rückwärtsreferenzen, heute wohl. Früher wurden in Tcl die schon sehr merkwürdigen Konstrukte ˹[:<:]˼ und ˹[:>:]˼ für Wortgrenzen benutzt. Sie funktionieren auch heute noch, aber in neuen Programmen sollten ˹\m˼, ˹\M˼ und ˹\y˼ (Wortanfang, Wortende, Wortgrenze) benutzt werden.
Programme wie grep und egrep stammen nicht von einem bestimmten Hersteller, es gibt deshalb mehrere Implementationen, und jeder kann ein Programm namens grep schreiben, das seinen eigenen Regex-Dialekt implementiert. Da der Menschen Geschmäcker sehr verschieden sind, erwachsen daraus sehr schnell besondere Features und Eigenheiten. (Die GNU-Versionen dieser Werkzeuge sind beispielsweise oft besser und robuster als andere.)
Vielleicht ebenso wichtig wie die unterstützten Features sind die vielen subtilen und weniger subtilen Unterschiede zwischen den einzelnen Dialekten. Angesichts der obigen Tabelle könnte man den Eindruck gewinnen, dass die Regex-Implementationen von Perl, .NET und Java identisch seien – weit gefehlt. Zu einer solchen Tabelle gibt es eine Reihe von Fragen:
- Können der Stern und die anderen Quantoren auf Klammerausdrücke angewendet werden?
- Enthält die Zeichenklasse »Punkt« das Newline-Zeichen? Enthalten negierte Zeichenklassen das Newline-Zeichen? Wie steht’s mit dem NUL-Zeichen?
- Sind Zeilenanker wirklich Zeilenanker (d.h., erkennen sie im Suchstring enthaltene logische Zeilen) oder eher Suchstringanker? Oder beides? Keins von beiden? Sind es vollwertige Metazeichen, oder sind sie nur an bestimmten Orten in regulären Ausdrücken zugelassen?
- Sind Escapes (mit Backslash) in Zeichenklassen erlaubt? Was ist sonst in Zeichenklassen erlaubt, und was ist verboten?
- Dürfen Klammern verschachtelt werden, und wenn, wie tief? Wie viele Klammerpaare sind im ganzen Ausdruck erlaubt?
- Wenn Rückwärtsreferenzen unterstützt werden und ohne Berücksichtigung von Groß- und Kleinschreibung gesucht wird – muss die Rückwärtsreferenz auch in Bezug auf Groß- und Kleinschreibung mit dem von der Klammer gefundenen Text übereinstimmen? Verhalten sich die Rückwärtsreferenzen auch in Grenzfällen richtig?
- Sind oktale Escapes (wie \123) erlaubt? Wenn sie erlaubt sind, wie wird der Konflikt mit Rückwärtsreferenzen aufgelöst? Gibt es hexadezimale Escapes? Ist es wirklich die Regex-Maschine, die oktale oder hexadezimale Escapes zulässt, oder ist es ein anderer Teil des Werkzeugs?
- Passt ˹\w˼ nur genau auf alphanumerische Zeichen oder auch auf andere? (Von den Programmen in der obigen Tabelle wird ˹\w˼ verschieden interpretiert.) Stimmt ˹\w˼ mit den Metazeichen für Wortgrenzen überein? Hängt die Interpretation von ˹\w˼ vom Locale ab? Funktioniert ˹\w˼ auch mit Unicode?
Vieles muss also berücksichtigt werden, auch bei einer netten kleinen Übersicht wie die vorige Tabelle. Solange man sich der schmutzigen Wäsche hinter der sauberen Fassade bewusst ist, macht das keine großen Probleme.
Wie eingangs des Kapitels erwähnt wurde, sind die meisten Unterschiede bloß syntaktischer Art. Manche aber gehen tiefer. Wenn man verstanden hat, dass ein regulärer Ausdruck aus egrep wie ˹(Jul|July)˼ für GNU Emacs so umgeschrieben werden muss: ˹\(Jul\|July\)˼, dann ist man versucht zu glauben, dass alles andere gleich sei. Das ist nicht immer der Fall – es gibt durchaus Situationen, bei denen scheinbar gleichwertige Ausdrücke verschiedene Resultate erbringen. Die semantischen Unterschiede, wie ein Muster gesucht wird (oder wie es scheint, dass die Regex-Maschine sucht), sind sehr wichtig, werden aber häufig übersehen. In diesem Fall erklären sie, warum diese zwei auf den ersten Blick äquivalenten Ausdrücke nicht das Gleiche finden: Der eine passt immer auf ›Jul‹, auch dann, wenn der Suchstring ›July‹ ist. Die gleichen semantischen Unterschiede erklären auch, warum im umgekehrten Fall, bei ˹(July|Jul)˼ und ˹\(July\|Jul\)˼, beide Programme den gleichen Text finden. Wie Regex-Maschinen arbeiten befasst sich mit diesen Unterschieden.
Natürlich ist es oft wichtiger zu wissen, was ein bestimmtes Programm mit einem regulären Ausdruck überhaupt tun kann, als zu wissen, wie es das tut oder welchen Regex-Dialekt es vertritt. Wenn die regulären Ausdrücke von Perl schwächlicher wären als die von egrep, wäre die größere Flexibilität, mit der man reguläre Ausdrücke in Perl anwenden kann, noch immer ein Gewinn. In diesem Kapitel untersuchen wir eine Anzahl von einzelnen Features, in späteren Kapiteln auch solche, die sich auf eine bestimmte Programmiersprache beziehen.
<< 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