Kommentare und Modus-Modifikatoren
(Auszug aus "Reguläre Ausdrücke" von Jeffrey E. F. Friedl)
In vielen Dialekten kann man mit den folgenden Konstrukten den Regex-Modus (siehe Regex-Modi) innerhalb der Regex setzen oder verändern, sozusagen im Vorbeigehen.
Modus-Modifikatoren: (?Modifikator), z.B. (?i) und (?-i)
Bei vielen Regex-Implementationen kann man bestimmte Regex-Modi innerhalb des regulären Ausdrucks steuern. Häufig ist die besondere Notation ˹(?i)˼ unterstützt, nach der ohne Rücksicht auf Groß- und Kleinbuchstaben gesucht wird, und ˹(?-i)˼, mit der man dieses Verhalten wieder abschaltet. Zum Beispiel wird bei ˹<B>(?i)sehr(?-i</B>)˼ nach dem ˹sehr˼-Teil in jeder Schreibweise gesucht. Bei den Tag-Namen kommt es aber noch immer auf die Groß- und Kleinschreibung an. Also würden ›<B>SEHR</B>‹ und ›<B>Sehr</B>‹ gefunden, nicht aber ›<b>Sehr</b>‹.
Dieses Beispiel funktioniert bei den meisten Systemen, die ˹(?i)˼ unterstützen – sicher in Perl, PHP, java.util.regex, Ruby (Anmerkung: In Ruby gibt es einen Bug: ˹(?i)˼ wirkt manchmal nicht auf Alternativen in Kleinbuchstaben – aber es funktioniert, wenn die Alternativen in Großbuchstaben angegeben werden!) und in den .NET-Sprachen. Python und Tcl unterstützen ˹(?-i)˼ nicht, daher funktioniert das Beispiel dort auch nicht.
In vielen Implementationen (außer bei Python) gilt ein ˹(?i)˼ innerhalb von Klammern nur bis zum Ende dieser Klammerung. ˹(?i)˼ wird also bei der schließenden Klammer automatisch wieder ausgeschaltet. Man kann in diesem Fall das ˹(?-i)˼ ganz einfach weglassen: ˹<B>(?:(?-i)sehr)<B>˼.
Diese Modus-Umschaltung mitten in der Regex funktioniert nicht nur mit dem /i-Modifikator. Bei vielen Systemen kann man alle in folgender Tabelle aufgeführten Modi benutzen. Manche Systeme kennen eine ganze Anzahl weiterer Modus-Modifikatoren, insbesondere PHP (siehe unter Pattern-Modifikatoren) und Tcl (siehe dazu die Tcl-Dokumentation).
Tabelle: Modus-Modifikatoren.
Buchstabe | Modus |
---|---|
i | Modus »Groß- und Kleinschreibung ignorieren« |
x | Modus »Freie Form« |
s | Modus »Punkt passt auf alles« |
m | Modus »verbesserte Zeilenanker« (Mehrzeilenmodus) |
Modus-Modifikatoren mit Klammerung: (?Modifikator:...), z.B. (?i:...)
Das »sehr«-Beispiel aus dem vorhergehenden Abschnitt kann man noch weiter vereinfachen, wenn das verwendete System die Modus-Umschaltung mit Klammerung beherrscht. Mit ˹(?i:...)˼ wird der /i-Modifikator nur für den eingeklammerten Unterausdruck aktiviert. Damit vereinfacht sich ˹<B>(?:(?i)sehr)<B>˼ zu ˹<B>(?i:sehr)<B>˼.
Wenn diese Form unterstützt wird, dann in der Regel für alle Buchstaben aus der obigen Tabelle. In Tcl und Python wird nur die ˹(?i)˼-Form, nicht aber die geklammerte Variante mit ˹(?i:...)˼ unterstützt.
Kommentare: (?#...) und #...
Bei manchen Dialekten sind Kommentare mit ˹(?#...)˼ erlaubt. In der Praxis wird das kaum benutzt, viel eher der Modus »Freie Form«. In Sprachen wie VB.NET, bei denen die literalen Strings eine sehr eingeschränkte Funktionalität haben, ist diese Art von Kommentaren ganz wertvoll (siehe unter Suchen und Ersetzen in VB.NET, Regex-Optionen).
Literaler Text: \Q...\E
Innerhalb der Sequenz \Q...\E werden alle Regex-Metazeichen zu literalen Zeichen, außer dem \E selbst. (Wenn kein \E vorkommt, werden alle Metazeichen bis zum Ende der Regex zu literalen.) So kann man auf einfache Weise verhindern, dass normaler Text als Regex interpretiert wird. Das ist besonders dann wertvoll, wenn man den Wert einer Variablen in einen regulären Ausdruck einfügt.
Zum Beispiel erhält man bei einem Web-Suchformular das vom Benutzer eingegebene Suchwort in $query, und wir suchen nach diesem Wort mit m/$query/i. So geschrieben, ergibt das bei Suchwörtern wie beispielsweise ›C:\WINDOWS\‹ einen Laufzeitfehler, weil das keine gültige Regex ergibt (wegen des Backslashs am Ende).
Mit m/\Q$query\E/i kann man das vermeiden; das transformiert den eingesetzten Wert ›C:\WINDOWS\‹ in ˹C\:\\WINDOWS\\˼, und die Suche ergibt ›C:\WINDOWS\‹, was der Benutzer wohl gemeint hat.
Diese Notation ist bei Systemen, die den prozeduralen oder den objektorientierten Ansatz benutzen (siehe Prozeduraler und objektorientierter Ansatz), weniger wichtig, weil da die regulären Ausdrücke normale Strings sind. Und diese Strings kann man vor der Mustersuche relativ einfach mit einer dafür vorgesehenen Funktion vor der Regex-Maschine »schützen«. In VB nimmt man dafür beispielsweise die Regex.Escape-Methode (siehe Regex-Escape(String)), in PHP die preg_quote-Funktion (siehe preg_quote), in Java die Methode quote (siehe unter Weitere Pattern-Methoden).
Soviel mir bekannt ist, wird das Konstrukt ˹\Q...\E˼ nur von den Regex-Maschinen von java.util.regex und PCRE (und damit PHP) voll unterstützt. Warum leistet Perl das nicht, wo doch das Beispiel in Perl war? Nun, in Perl ist \Q...\E nur in Regex-Literalen erlaubt (also in regulären Ausdrücken, die direkt in den Programmcode eingegeben werden), nicht aber im Inhalt von Variablen, die interpoliert werden. Mehr dazu in Perl (siehe unter Eigenschaften von Regex-Literalen).
Die Implementation von ˹\Q...\E˼ in java.util.regex vor Java 1.6.0 ist innerhalb von Zeichenklassen fehlerhaft und sollte nicht verwendet werden.
<< 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