|
|
8.5. Welche Bauelemente kommen in Regulären Ausdrücken vor?
Suchmuster in regulären Ausdrücken bestehen aus gewöhnlichen
Zeichen und Zeichen mit einer Sonderbedeutung. Gewöhnliche
Zeichen in Suchausdrücken stehen für die entsprechenden Zeichen
in einem String. Der Suchausdruck hallo paßt also auf alle
Strings, die irgendwo genau diese Zeichenfolge enthalten.
Zeichen mit Sonderbedeutung stehen als Platzhalter für ein oder
mehrere andere Zeichen, für Zeilenanfänge oder -enden oder für
andere Sonderfunktionen. Sie sind es, die reguläre Ausdrücke
eigentlich mächtig und sinnvoll machen.
In regulären Ausdrücken gibt es Zeichenmengen (wird weiter
unten erklärt), die durch eckige Klammern [ und ]
eingeschlossen werden. Bei Zeichen mit Sonderbedeutung gelten
leicht unterschiedliche Regeln, je nachdem ob man gerade eine
außerhalb einer Zeichenmenge arbeitet oder innerhalb.
Außerhalb von Zeichenmengen gibt es die folgenden besonderen
Regeln:
-
Der Backslash \ wird als Escape-Zeichen verwendet,
mit unterschiedlichen Anwendungen:
-
Für Sonderzeichen (also alle nicht-alphanumerischen
Zeichen) nimmt es den Zeichen ihre besondere Bedeutung,
sodass man sie "wörtlich" in das Suchmuster einfügen kann.
Das Suchmuster \* paßt also auf genau ein
Sternchen.
-
Für alphabethische Zeichen hat es eine besondere
Bedeutung ähnlich wie in der Programmiersprache C:
\r steht für ein Return (ASCII 13), \n
steht für ein Linefeed (ASCII 10) und so weiter. Die
Zeichenfolgen \d, \D, \w,
\W, \s und \S beschreiben
bestimmte vordefinierte Zeichenmengen (siehe unten).
-
In Zeichenfolgen \xYY definiert es das Zeichen
mit dem hexadezimalen Zeichencode YY. Ein
\x0A steht also für ein Zeichen mit einem
Zeichencode ASCII 10, Linefeed.
-
In Zeichenfolgen \YYY definiert es das Zeichen
mit dem oktalen Zeichencode YYY. Ein
\012 steht also für ein Zeichen mit dem
Zeichencode ASCII 10, Linefeed. Diese Schreibweise ist
jedoch nicht empfohlen, weil sie sich mit einer anderen
Schreibweise für sogenannte Backreferences
(siehe unten) überlappt.
-
Das Dachzeichen ^ steht als Markierung für einen
Stringanfang: Das Suchmuster ^hallo paßt auf alle
Strings, die mit dem Wort hallo beginnen, jedoch
nicht auf Strings, die hallo irgendwo in der Mitte
enthalten.
-
Entsprechend steht das Stringzeichen $ für ein
Stringende: Das Suchmuster Welt!$ paßt auf
Zeichenketten, die mit dem Text Welt! enden. Das
Suchmuster ^$ paßt auf Strings, die nur aus einem
Beginn und einem Ende bestehen, also auf Leerstrings.
-
Der Punkt . paßt auf genau ein beliebiges Zeichen
außer dem Zeilenendezeichen \n. Das Suchmuster
... paßt also auf alle Strings, die aus genau drei
Zeichen bestehen.
-
Die öffnende eckige Klammer [ leitet eine
Zeichenmenge ein.
-
Das Pipelinezeichen | kennzeichnet einen Zweig
einer Alternative. So paßt das Suchmuster (Sie|Du),
sobald die Zeichenfolge Sie oder die Zeichenfolge
Du im Text enthalten ist.
-
Die runden Klammern () schließen ein Untermuster
bzw. Teilmuster ein. Man kann dies verwenden, um einen
Teilbereich eines Suchmusters zum Zwecke der späteren
Verwendung zu markieren oder um Teilmuster zu gruppieren.
Für die Gruppierung findet man im vorhergehenden Punkt schon
ein Beispiel: (Sie|Du) definiert ein Muster, das
auf Sie oder Du paßt. Dagegen
definiert Si(e|D)u ein Muster, das entweder auf
Sieu oder auf SiDu paßt.
Markierte Teilbereiche eines Suchmusters, sogenannte
Backreferences lassen sich später nach der
Anwendung des Musters extrahieren und weiterverarbeiten: Das
Muster "(.)" paßt auf genau ein beliebiges Zeichen,
das zwischen Anführungszeichen steht. Welcher Buchstabe aus
dem getesteten String genau gepaßt hat, kann man nach der
Anwendung des Suchmusters erfragen. Dies verwendet man oft,
um Teilstrings mit einem bestimmten Aussehen aus einem
größeren String herauszuschneiden.
Innerhalb eines regulären Ausdrucks werden die öffnenden
runden Klammern von links nach rechts durchnummeriert.
Innerhalb desselben Ausdrucks kann man sich mit
Backreferences auf den Text beziehen, der von einer
Klammer markiert worden ist: \1 bezeichnet den
Text, der von der ersten öffnenden Klammer umschlossen wird,
\2 den Text in der zweiten Klammer und so weiter.
Dazu in einem der folgenden Punkte mehr.
-
Mit Hilfe von Quantifizierern in geschweiften Klammern
{} kann man festlegen, wieviele Wiederholungen des
vorhergehenden Ausdrucks gesucht werden: {n,m}
steht für n bis m Wiederholungen des
vorhergehenden Ausdrucks, {n,} für mindestens
n Wiederholungen, {,m} für maximal
m Wiederholungen. Mit Hilfe von {n}
bezeichnet man genau n Wiederholungen.
So paßt das Suchmuster a{3,5} auf alle Strings,
die zwischen 3 und 5 Zeichen a in Folge enthalten.
Das Muster (bla){3} paßt auf alle Strings, die
genau die Zeichenfolge blablabla enthalten und das
Muster ^a(.{3,})b$ paßt auf alle Strings, die mit
einem a anfangen, mit einem b enden und
die dazwischen mindestens 3 Zeichen enthalten. Welche (und
wieviele) Zeichen dies waren, kann man nach Anwendung des
Musters abfragen, da dieser Bereich im Muster mit runden
Klammern markiert war.
-
Das Fragezeichen ? kann als Kürzel für
{0,1} verwendet werden: Es steht für null oder eine
Wiederholung des vorhergehenden Ausdrucks.
-
Der Stern * steht für {0,}, also für Null
oder mehr Wiederholungen des vorhergehenden Ausdrucks.
-
Das Pluszeichen steht für {1,}, also für mindestens
eine Wiederholung des vorhergehenden Ausdrucks.
Eckige Klammern leiten eine Zeichenmenge ein. Eine Zeichenmenge
steht immer für genau ein Zeichen und zwar für ein Zeichen, das
in der Menge enthalten ist. Also paßt der reguläre Ausdruck
[0123456789] auf genau eine beliebige Ziffer. Innerhalb
der eckigen Klammern einer Zeichenmenge haben die folgenden
Zeichen eine besondere Bedeutung:
-
Der Backslash \ gilt als Escapezeichen: Das ihm
folgende Zeichen hat keine besondere Bedeutung, sondern steht
nur für sich selbst.
-
Das Dach ^ als erstes Zeichen einer Zeichenmenge
(aber nur als erstes Zeichen!) negiert die Zeichenmenge. Die
Zeichenmenge [^0123456789] steht also für genau ein
Zeichen, das keine Ziffer ist.
-
Das Minuszeichen - definiert einen Bereich. Die
Zeichenmenge [0-9] ist also eine kürzere Schreibweise als
[0123456789] für dieselbe Menge.
-
Die besonderen Zeichenmengen \d (eine dezimale
Ziffer), \D (die Negation von \d),
\w (ein "Wort"-Zeichen), \W (die Negation
von \w), \s (ein "Whitespace"-Zeichen) und
\S (die Negation von \s) stehen für die jeweils
angegebenen Zeichen.
Verwendet man einen Suchausdruck mit den preg*-Funktionen, dann
ist der Suchausdruck in sogenannte Begrenzerzeichen
(Delimiter) einzuschließen, hinter denen noch Optionen mit angegeben werden können. Meistens
verwendet man entweder die Schrägstriche / oder
Gleichheitszeichen =.
Aus diesen Komponenten kann man sich mit einiger Übung
Suchausdrücke zusammenbauen, die nicht nur weitgehend unlesbar
sind, sondern die außerdem schnell und schmerzlos die
gewünschten Suchfunktionen oder Such- und Ersetzefunktionen
durchführen.
|