Ein regulärer Ausdruck ist ein Muster, das auf eine
Zeichenkette von links nach rechts angewendet wird. Die
meisten Zeichen in dem Ausdruck stehen dabei für sich
selbst und werden mit den Zeichen des zu durchsuchenden
Textes verglichen. So passt das Muster
kleiner dicker Zwerg
auf einen dazu identischen Abschnitt des zu durchsuchenden
Textes. Die Stärke regulärer Ausdrücke ist jedoch die
Möglichkeit Alternativen und Wiederholungen ins Muster
einzufügen. Diese werden durch sogenannte Meta-Zeichen
dargestellt, welche nicht für sich selbst stehen, sondern
auf besondere Weise ausgewertet werden.
Es gibt oft Fälle, in denen man aber nicht ein Muster
fester Länge sucht, sondern eines, welches nur eine bestimmte
Struktur erfüllt. Will man z.B. eine Zeichenkette finden
die mit 'b' startet und durch eine Anzahl 'a' fortgesetzt
werden, so kommen sogenannte Quantifier ins Spiel. Dabei
handelt es sich um Zeichen (oder Kombinationen davon) die
eine Wiederholung des vorangehenden Zeichens oder Teilmusters
erlauben. Für das Beispiel wären dies:
ba* | 'b' gefolgt von 0 bis bel. vielen 'a' |
ba+ | 'b' gefolgt von 1 bis bel. vielen 'a' |
ba? | 'b' gefolgt von einem optionalen 'a' |
ba{3,} | 'b' gefolgt von min. 3 'a' |
ba{,5} | 'b' gefolgt von max. 5 'a' |
ba{3,5} | 'b' gefolgt von 3 bis 5 'a' |
Um aber sinnvollere Muster zu erzeugen braucht man zum
Beispiel oft Alternativen. Die werden durch den senkrechten
Strich getrennt, so steht also das Muster
Zwerg|Elf
für Zwerg oder Elf. Soll nur ein Teil des Musters
aus Alternativen bestehen, so klammert man den
Abschnitt. Als Erweiterung zu unserem ersten Muster
kann man also z.B.
kleiner (dicker|bärtiger) Zwerg
verwenden um sowohl kleine dicke, als auch kleine
bärtige Zwerge zu finden.
Die Quantifier können auch auf geklammerte Ausdrücke
angewendet werden und bewirken dann eine wiederholte
Anwendung des Musters innerhalb der Klammern, also
könnte man zum Beispiel schreiben:
1(0|1)+0
Das ist ein Muster, das auf Zahlen zutrifft die mit
1 beginnen, dann ein bis bel. viele Einsen und Nullen
enthalten und durch eine 0 beendet werden.
Will man aber z.B. auf Einheitennummern in
Base 36 ein Muster definieren, so wäre es sehr
mühsam alle 36 Zeichen als Alternativen aufzuführen.
Darum gibt es die Zeichenklassen. Dabei handelt es sich
um eine Möglichkeit Zeichenmengen zu definieren, aus
denen dann die Alternaiven gewählt werden. So ist
z.B.
0|1|2|3|4|5|6|7|8|9
identisch mit der Zeichenklasse
[0123456789]
Beide Ausdrücke stehen also für eine Ziffer von 0-9.
Aber es gibt noch eine wesentliche Möglichkeit zur
Vereinfachung. Innerhalb von Zeichenklassen sind
nämlich Intervalle erlaubt. So kann man für die
Ziffern auch schreiben:
[0-9]
Eine gültige Base36-Ziffer wäre also durch die Klasse
[0-9a-zA-Z]
definiert. Dabei wurde hier Groß- und Kleinschreibung
aufgenommen.
So wäre also eine gültige Einheitennummer bei Eressea
zur Zeit:
[0-9a-zA-Z]{1,4}
also min. 1 und max. 4 Base36-Ziffern.
Innerhalb von Zeichenklassen können noch weitere
Vereinfachungen durch Sonderzeichen erreicht werden.
Folgende Sequenzen stehen zur Verfügung:
\d | eine bel. Dezimalziffer |
\D | ein bel. Zeichen das keine Dezimalziffer ist |
\s | ein bel. Whitespace-Zeichen, also Leerzeichen, Tabulatoren, Zeilenumbrüche, etc. |
\S | ein bel. Zeichen das kein Whitespace ist |
\w | ein bel. Wortzeichen (Buchstabe, Ziffer oder Unterstrich), jedoch keine Umlaute und kein 'ß' |
\W | ein bel. Nicht-Wortzeichen |
ACHTUNG: Es ist zu beachten, dass auch in Vorlage und Eressea
ja der Backslash benutzt wird um Zeichenfunktionen
aufzuheben. Daher müssen in regulären
Ausdrücken in Textkonstanten alle Backslashes durch zwei
Backslashes eingegeben werden. Aus [\d\w] wird also [\\d\\w] und
will man einen Backslash in einem Ausdruck als Zeichen für sich
selber verwenden, muss man, da er ja auch selber escaped, also seiner
normalen Funktion beraubt werden muss, vier Backslashes benutzen.
Will man z.B. nach der Zeichenkette \n suchen, also aus den beiden Zeichen Backslash
und 'n' bestehend, und nicht die Zeilenende-Sequenz, z.B. um
diese Folge in externen Dateien zu ermöglichen, so lautet der
reguläre Ausdruck dafür \\n weil der Backslash für den Ausdruck
entwerten muss, der Vorlage-String für den Ausdruck ist aber
'\\\\n' weil die beiden Backslashes des regulären Ausdrucks
ihrerseits in Vorlage-Strings entwertet werden müssen. Das ist
nicht immer einfach, aber ein Problem das auch reguläre Ausdrücke
in Sprachen wie C, C++ oder Java haben wenn sie sich an Perl
orientieren.
Wird dieses Wissen umgesetzt, so wird also aus unserem Muster
für Base36-Zahlen in einem Vorlage-String:
'[\\da-zA-Z]{1,4}]'
Wir haben kein \w verwendet, weil da ja auch noch mindestens ein anderes
Zeichen (Unterstrich) drin ist.
Will man zum Beispiel alle Zeichen außer Ziffern und Buchstaben haben, kann man mit der Negation arbeiten:
[^0-9a-zA-Z]
Das '^' zu Beginn einer Zeichenklasse bedeutet, dass diese
komplett negiert wird. Es hat nur am Anfang der Zeichenklasse diese Bedeutung und kann an jeder anderen Stelle für sich selbst stehen.
Die hier genannten Unterschiede beziehen sich auf den Stand von Perl 5.005.
- Normalerweise ist ein Whitespace-Zeichen, da
isspace()
der ANSI-C-Bibliothek verwendet wird, ein Zeichen,
das keine sichtbare Darstellung hat. Dies sind hier
Leerzeichen, Zeilenvorschub, Zeilenumbruch, horizontaler
Tabulatur und vertikaler Tabulator. Mit Perl 5 gilt der
vertikale Tabulator nicht mehr als Whitespace.
- Wiederholungsangaben können für Lookahead-Bedingungen nicht
benutzt werden. In Perl ist das zwar erlaubt, führt aber
nicht zu einem erwarteten Ergebnis. So stellt z.B.
(?!a){3} nicht etwa sicher, dass die folgenden drei Zeichen
kein 'a' sind, sondern es wird dreimal überprüft dass das
nächste Zeichen kein 'a' ist.
- Unterausdrücke die innerhalb von negativen
Lookahead-Bedingungen vorkommen, werden zwar mitgezählt,
aber ihr Inhalt wird nie gesetzt. Perl hingegen setzt die
Werte, wenn die Bedingung nicht zutraf, aber nur wenn die
negative Lookahead-Bedingung nicht verzweigt.
- Die binäre Null ist in Suchmustern nicht erlaubt.
- Die Escape-Sequenzen
\l , \u , \L , \U , \E und \Q
werden nicht unterstützt. Diese sind auch in Perl Teil der
normalen Zeichenkettenbehandlung und nicht der regulären
Ausdrücke.
- Die Bedingung \G wird nicht unterstützt.
- Die Konstruktionen
(?{code}) und (?p{code}) werden
nicht unterstützt, da ja kein Perl zur Verfügung steht.
Revision 03 Jan 2006
|