
Previous: PHP & HTTP
Up: Einführung PHP
Next: Fehlersuche
? Es gibt
Leute, die finden reguläre Ausdrücke fast so genial wie die Erfindung des geschnittenen
Brotes: Im Prinzip sind reguläre Ausdrücke Suchmuster, die sich auf Strings (Zeichenketten)
anwenden lassen. Auf den ersten Blick sehen sie etwas kryptisch aus, was sie durchaus auch
sein können. Was sie aber so sinnvoll macht ist ihre Fähigkeit, komplexe Suchen
durchzuführen - mehr dazu im folgenden.
Anfängern empfehle ich, dieses Kapitel erstmal zu überspringen. Alles, was man mit regulären Ausdrücken realisieren kann, kann auch mit normalen Befehlen programmiert werden, ist dann aber natürlich etwas länger. Mit regulären Ausdrücken ist es einfach eleganter.
In Unix-Programmen, vor allem in Perl
,
werden die regulären Ausdrücke sehr gerne benutzt, wenn normale Suchmuster nicht mehr
ausreichen. Auch wenn einfache Suchmuster noch relativ einfach zu erstellen sind, kann das
beliebig kompliziert werden. Nicht umsonst gibt es dicke Bücher, die sich nur mit diesem
Thema beschäftigen.
Wann sollen denn nun die regulären Ausdrücke eingesetzt werden? Die Antwort ist ganz einfach: Wenn man nach Mustern suchen will, bei denen die normalen Funktionen nicht mehr ausreichen. Wenn hingegen die normalen String-Funktionen, wie z.B. str_replace() oder strpos(), ausreichen, sollten diese auch benutzt werden, weil sie schneller abgearbeitet werden.
PHP kennt zwei verschiedene Funktionsgruppen von regulären Ausdrücken, die ereg*-
und die preg*-Funktionen. Erstere sind von Anfang an dabei, halten sich an die
POSIX-Definition, sind aber langsamer und nicht so leistungsfähig wie die letzteren, die
sich an Perl orientieren. Von daher sollten, wenn möglich, die preg*-Funktionen
verwendet werden. In Konsequenz werde auch ich hier die Perl-kompatiblen Funktionen
verwenden; diese werden auch häufig als PCRE
-Funktionen bezeichnet.
Mit regulären Ausdrücken ist es wie mit Programmen (und Dokus ;-)): Es ist eine Kunst, gut, verständlich, fehlerfrei und effizient zu schreiben, und mit der Zeit perfektioniert man sein Können. Von daher: Nicht verzweifeln, wenn es am Anfang nicht funktioniert oder man Minuten braucht, bis dieser 20 Zeichen lange Ausdruck steht - üben, probieren und nochmals üben. Irgendwann geht es.
Z.B. sucht das Muster /<title>/ nach dem HTML-Tag <title>. Wenn man jetzt aber Header-Tags (<h1>,<h2>,...,<h6>) finden will, funktioniert das so nicht mehr. Hier braucht man einen Platzhalter. Das, was auf der Kommandozeile der Stern * und in SQL bei LIKE das Prozentzeichen % ist, ist hier der Punkt .. Das Muster /<h.>/ würde auf alle HTML-Tags zutreffen, bei denen auf das h ein beliebiges Zeichen folgt. Wir wollten aber nur die Zahlen 1-6. Mit \d steht ein Platzhalter für eine beliebige Zahl zur Verfügung. /<h\d>/ trifft nur noch die HTML-Tags <h0>,<h1>,<h2>,...,<h9>. Das ist zwar schon besser, aber auch noch nicht perfekt. Man bräuchte genau die Menge der Zahlen 1,2,3,4,5,6. Dies ist selbstverständlich auch möglich: Der Ausdruck /<h[123456]>/ bewirkt das Gewünschte, er läßt sich aber noch verschönern zu /<h[1-6]>/.
Wie wir gesehen haben, kann mit Hilfe der eckigen Klammern [] eine Menge von Zeichen
definiert werden, indem man entweder alle aufzählt oder den Bereich angibt. Wenn man das
Dach ^ als erstes Zeichen angibt, wird die Auswahl negiert.
|
|
Das Dach ^ hat auch im Muster eine besondere Bedeutung: es markiert den
Stringanfang. Der Ausdruck /^Hallo/ paßt auf alle Strings, bei
denen das Wort ,Hallo` am Anfang steht, nicht jedoch in der Mitte. Neben dem
Anfang ist natürlich auch das Ende interessant, das mit einem Dollar $ markiert
wird. Das Suchmuster /Welt!$/ paßt demnach auf alle Strings, die mit dem Wort
,,Welt!`` enden. Das läßt sich natürlich auch kombinieren: Mit
/^Hallo Welt!$/ findet man genau die Strings
,,Hallo Welt!`` .
Zur Vertiefung und Übung habe ich versucht, ein paar Beispiele zu erfinden. Diese befinden sich bei den Übungen am Ende des Kapitels.
Da wäre als erstes der altbekannte Stern *, der für ,,keinmal`` oder ,,beliebig oft`` steht. Das Suchmuster /^\d*$/ würde z.B. alle Strings, die aus keiner oder beliebig vielen Ziffern bestehen, finden. Wie man an dem Beispiel sieht, muß der Quantifizierer immer hinter dem Zeichen bzw. der Zeichenmenge stehen. Neben dem Stern *, Allquantor genannt, gibt es noch das Fragezeichen ?, das für keinmal oder einmal steht und Existenzquantor genannt wird, sowie das Pluszeichen + (mind. einmal).
|
Wenn man aber genau fünf Zahlen oder zwischen drei und sieben kleine Buchstaben haben will, reichen die bisherigen Quantifizierer dann doch noch nicht. Deshalb gibt es noch die geschweiften Klammern {}, in die man die gewünschten Zahlen eintragen kann. Das Suchmuster für genau fünf Zahlen sieht z.B. so aus: /\d{5}/; das für die drei bis sieben kleinen Buchstaben so: /[a-z]{3,7}/.
Auch hier gibt es zur Vertiefung Übungen am Ende des Kapitels.
Die markierten Teilbereiche eines Ausdruckes werden auch Backreferences genannt. Sie werden von links nach rechts durchnumeriert. Innerhalb eines Ausdruckes kann man sich mit \1 auf den Text, der von der ersten Klammer eingeschlossen wird, beziehen, mit \2 auf den zweiten usw. Der Ausdruck /(\w)\s\1/ paßt immer dann, wenn zweimal dasselbe Wort nur durch ein Leerzeichen getrennt vorkommt.
Zur allgemeinen Verwirrung gibt es auch hier am Ende des Kapitels Übungen.
Up: Einführung PHP
Previous: PHP & HTTP
Next: Fehlersuche