Teil von  SELFPHP   Teil von  Praxisbuch  Teil von  Reguläre Ausdrücke
Letztes Update: 16.08.2005 17:53:45


Navigation

Seite News *

Seite Startseite
Seite Über SELFPHP
Seite Werbung
Seite Kontakt
Seite Forum *
Seite Download *
Seite SELFPHP Banner *
Seite SELFPHP in Buchform
Seite Newsletter *
Seite Impressum

 
* Link führt ins Internet


Anbieterverzeichnis
Informieren Sie sich über die Unternehmen in unserem Anbieterverzeichnis!  

 


SELFPHP Forum
Fragen rund um die Themen PHP? In über 79.000 Beiträgen finden Sie sicher die passende Antwort!  


Newsletter
Abonnieren Sie hier den kostenlosen SELFPHP Newsletter!

Vorname: 
Name:
E-Mail:
 



 

Vertiefung zu reguläre Ausdrücke




Wir hoffen Sie haben die bisherigen Ausführungen zu reguläre Ausdrücke gut verdaut und denken Sie daran Übung macht den Meister. Der folgende Abschnitt zeigt Ihnen weitere Schwerpunkte auf.


Rückwärts-Referenzen (Back Reference)

Ausserhalb einer Zeichenklassendefinition kann auf referenzierte Teilmuster verwiesen werden. Das Muster verweist damit partiell auf Teile seiner selbst. Diese Rückreferenz wird mit der Zeichenfolge \N erreicht, wobei N für eine Ziffer zwischen 1 und 9 steht. Die Zählung erfolgt anhand der Anzahl der öffnenden (linke) runden Klammern der Teilmusterausdrücke.

Ein Fehler wird nur dann erzeugt, wenn die Anzahl der Klammern geringer ist als die durch eine Rückreferenz verlangte Ziffer. Stimmt die Anzahl, wird kein Fehler erzeugt, wenn die Referenz nichts enthält. Dabei kann die Referenz an jeder Stelle stehen, die Teilmuster dürfen sich jedoch nicht links davon befinden. Auf die Auswahl mit Hilfe des Backslash wurde weiter oben bereits eingegangen. Dieser Abschnitt zeigt den Umgang mit den Referenzen an sich.

Eine Rückreferenz findet Übereinstimmungen mit einem Suchmuster entsprechend dem referenzierten Teilmuster. Hier einige Beispiele:

Teil AusdruckBedeutung
(Kapital|Kommun) und ismusDieses Muster findet "Kapital und Kapitalismus" und Kommunismus, aber nicht "Kapitel und Kommunismus".
((?i)bum)\s+Hier wird "bum bum" und "BUM BUM" gefunden, aber nicht "BUM bum".


Es sind generell 99 rückwärtige Referenzen erlaubt. Alle Ziffern hinter einem Backslash werden daher als Referenznummer gewertet. Um unmittelbar folgende Ziffern abzugrenzen, muss ein Leerzeichen oder Kommentar gesetzt werden. Leerzeichen sind nur erlaubt, wenn die Option PCRE_EXTENDED gesetzt wurde.


Bedingungen

Eine Bedingung wird für das vorhergehende oder folgende Zeichen eines untersuchenden Zeichens aufgestellt. Sinngemäss entspricht dies Formulierungen wie: "Stimme mit a überein, wenn vor/nach a etwas bestimmtes steht".

Einige besonders einfache Bedingungsoperatoren wurden bereits beschrieben:

\b \B \A \Z \z ^ $

Im folgenden Abschnitt werden komplexere Bedingungen vorgestellt. Grundsätzlich wird zwischen folgenden Bedingungen unterschieden:
. Die nach der aktuellen Position (look ahead, vorrauschschauend) testen.
. Die vor der aktuellen Position (look behind, zurückschauend) testen.

Die Funktionsweise entspricht allen anderen Abfragekonstruktionen, lediglich die Position des Abfragezeigers im Suchwort wird nicht beeinflusst. Bedingungen werden mit dem ?-Zeichen eingeleitet:
. (?= leitet eine vorrausschauende, übereinstimmende Bedingung ein.
. (?! leitet eine vorrausschauende, nicht übereinstimmende Bedingung ein.


Teil Ausdruck Bedeutung
\w+(?=;) Dieses Muster sucht Wörter, die von einem Semikolon gefolgt werden, bezieht das Semikolon selbst jedoch nicht in die Auswertung mit ein.
test(?!feld) Hier werden Übereinstimmungen mit dem Wort "test" gesucht, das nicht von dem Wort "feld" gefolgt werden darf.
(?!test)feld Dagegen findet eine Übereinstimmung nicht, die mit etwas anderem als "test" beginnt. Es findet jedoch jede Übereinstimmung mit "feld", da die Sequenz (?!test) immer wahr ist.


Das Problem des letzten Musters ist nur mit weiteren Operatoren zu lösen. Die vorgestellten Beispiele bezogen sich auf vorausschauende Bedingungen. Folgende Symbole dienen der Definition zurückschauender Bedingungen:
. (?<= leitet eine zurückschauende, übereinstimmende Bedingung ein.
. (?
Betrachten wir uns nun nochmals das letzte Muster

Teil Ausdruck Bedeutung
(?Hier wird jede Übereinstimmung von "feld" gefunden, die nicht dem Wort "test" folgt.


Bei dieser Form muss die Länge der abhängigen Zeichenketten mit der zu testenden übereinstimmen:

Teil Ausdruck Bedeutung
(?<=auto|pkw) Ist zulässig.
(?Ist Falsch.


Ein weiteres Beispiel verdeutlicht dies und zeigt, wie man damit umgeht:

Teil Ausdruck Bedeutung
(?<=ab(c|de)) Funktionier nicht, da die alternativen Teilmuster "c" und "de" unterschiedlich lang sind.
(?<=abc|abde) Erfüllt den Zweck, denn nun wurde nur ein Teilmuster definiert.


Die Formulierung der rückwärtigen Bedingungen könnte man so aufschreiben:

"Nimm jede Alternative, gehe temporär um die Länge des alternativen Suchmusters zurück, prüfe das Muster erneut". Es ist daher logisch, dass eine fehlende Übereinstimmung der Länge zu keiner Übereinstimmung der Muster führen kann.

Teil Ausdruck Bedeutung
(?<=\d{3})(?Dieses Muster erkennt Suchworte, bei denen das Wort "test" drei Ziffern folgt, die aber nicht "999" sein dürfen. Übereinstimmungen gibt es z.B. für "250test" oder 777test".
(?<=(?Dieses Muster erfüllt das Wort "felder", aber nicht "testfelder".


Wenn Sie Bedingungen bilden, stehen diese in runden Klammern. Dies sind keine Teilmuster und sie werden auch nicht referenziert. Sie dürfen auch nicht wiederholt werden, dies wäre sinnlos, denn entweder stimmt es überein oder nicht. Wiederholungen ändern nichts am Ergebnis. Stehen allerdings Teilmuster in Bedingungen, werden diese gezählt und referenziert, wenn es positive Bedingungen sind.


Einmalige Teilmuster

Wenn ein Unter- und eine Obergrenze für Wiederholungen angegeben wird, führt eine fehlende Übereinstimmung zu einem wiederholten Test, bis alle durch die Wiederholungen gebildeten Muster geprüft wurden. Dies soll in manchen Fällen verhindert werden, um unnütz und zeitraubende Tests zu vermeiden, wenn das Ergebnis absehbar ist. Sehen Sie sich hierzu folgendes Beispiel an:

Das Muster \d+test wird auf die Zeichenkette "123456feld" angewendet.

Offensichtlich gibt es keine Übereinstimmung. Dennoch dauert die Überprüfung recht lange, denn der reguläre Ausdruck wird zuerst für sämtliche sechs Ziffern untersucht, dann wird das Wort "feld" verglichen. Anschliessend startet der Ausdruck erneut, diesmal mit nur fünf Ziffern usw. Insgesamt wird der Test sechsmal durchlaufen, obwohl schon beim ersten Durchlauf erkannt werden sollte, dass eine Übereinstimmung nicht möglich ist. Dies Ursache liegt in der konsequenten Abarbeitung von links nach rechts.

Der Ausdruck funktioniert zwar, ist aber nicht elegant programmiert. Es gibt die Möglichkeit, das Verhalten zu beeinflussen und damit den Ablauf zu optimieren:
. (?> weist den Interpreter an, sofort aufzugeben, sobald keine Übereinstimmung gefunden wurde.

Ein weiteres Beispiel verdeutlicht dies:

(?>\d+)feld

Eine andere Beschreibung dieses Typs ist die Annahme, dass diese Konstruktion einer alternativen Zeichenkette entspricht, die am aktuellen Auswertpunkt verankert ist, etwa wie folgt: \d\d\d\d\feld, wobei die Anzahl der Ziffern dennoch variabel ist, was eben ohne eine derartige Konstruktion nicht der Fall wäre.

Solche einmaligen Teilmuster sind keine zählenden Teilmuster, werden also auch nicht referenziert. Dafür können die Konstruktionen verschachtelt und mit Bedingungen kombiniert werden.


Fallbeispiel

. Ein einfaches Muster wie abcd$ wird auf eine lange Zeichenkette angewendet, die keine Übereinstimmung bietet. Hierbei sucht der Interpreter nach "a", findet er eines, wird der Rest auf die folgenden Zeichen getestet.
. Bei dem Suchmuster ^.*abcd$ wird hingegen sofort die gesamte Zeichenkette getestet. Wird keine Übereinstimmung gefunden, wiederholt sich der Vorgang mit einem Zeichen weniger usw.
. Besser wird es mit ^(?>.*)(?<=abcd). Hier wird nicht rückwärts die Suchfolge verringert, sondern die eingeschlossene Bedingung führt zum Abbruch der Suche, wenn die Zeichenfolge nicht sofort gefunden wird.

Bei langen Suchworten kann dies zu einer deutlichen Steigerung der Suche und damit der Performance führen.


Bedingte Teilmuster
Die Frage die sich nun noch stellt lautet, ist es möglich Teilmuster insgesamt von einer Bedingung abhängig zu machen? - Die Antwort auf diese Frage kennen sich sicher bereits. Um Teilmuster insgesamt von einer Bedingung abhängig zu machen, darf das Teilmuster nur dann untersucht werden, wenn die Bedingung erfüllt wurde. Dies lässt sich auf die Auswahl aus zwei Alternativen bilden. Die Schreibweise ähnelt dem einfachen Bedingungsoperator (Konditionaloperator) in PHP.
. (?(Bedingung)true-muster)
. (?(Bedingung)true-muster|false-muster)

Wenn die Bedingung erfüllt ist, wird das true-muster ausgeführt, andernfalls das false-muster. Werden mehr Alternativen angegeben, wird ein Laufzeitfehler erzeugt.


Kommentare

Ihnen stehen auch bei regulären Ausdrücken Zeichen zur Kommentierung zur Verfügung. Kommentare eignen sich hervorragend zur Beschreibung des regulären Ausdrucks. Die Kommentare werden, wie folgt umgesetzt:

(?#Hier ein Kommentar)

Wenn die Option PCRE_EXTENDED gesetzt wurde, kann ausserhalb einer Zeichenklassendefinition eine Kommentar allein mit dem #-Zeichen eingeleitet werden. Der nächste Zeilenumbruch beendet den Kommentar.


 


Ergänzungen zu reguläre Ausdrücke
 




 sponsored by

Host Europe


HighText iBusiness


Host Europe




© 2001-2006 E-Mail SELFPHP - Damir Enseleit, info@selfphp.deImpressumKontakt
© 2005-2006 E-Mail PHP5 Praxisbuch - Matthias Kannengiesser, m.kannengiesser@selfphp.de