preg_replace, pattern syntax speziell: Zeichenklassen
Verfasst: 16.04.2006 16:32
ich versuche mich an eigenen search und replace regeln.
dafür möchte ich erstmal exakt die variante verstehen, die phpbb in der bbcode.php verwendet:
ich nehme das mal soweit auseinander, wie ich das verstehe:
Dinge, die mir nicht ganz klar sind, habe ich fett geschrieben.
Gruß
dafür möchte ich erstmal exakt die variante verstehen, die phpbb in der bbcode.php verwendet:
Code: Alles auswählen
$ret = preg_replace("#(^|[\n ])([\w]+?://[\w\#$%&~/.\-;:=,?@\[\]+]*)#is", "\\1<a href=\"\\2\" target=\"_blank\">\\2</a>", $ret);
- "$ret =" -> der Variable wird ein Inhalt zugewiesen
- " preg_replace() -> die Funktion "preg_replace(Suchmuster, Ersatz, Zeichenkette)" wird aufgerufen.
- " -> Suchmuster beginnt
- # -> Startmarkierung (kann beliebig sein, phpBB verwendet in der Regel das Rautezeichen
- () -> Klammer stellen hier Teilsuchmuster dar. D.h. die Zeichenkette wird auf bestimmte Teile untersucht. In diesem Fall haben wir zwei Teilsuchmuster: (^|[\n ]) und ([\w]+?://[\w\#$%&~/.\-;:=,?@\[\]+]*). Das Teilsuchmuster wird durchnummeriert und kann dann im Ersatzteil einzeln zugewiesen werden. Das erste Teilsuchmuster wird zu \\1 und das zweite zu \\2 usw.
- ^ -> Beginn einer Zeile (z.b. ein Link direkt am Anfang eines Beitrages, hat kein Leerzeichen oder Zeilenumbruch davor und würde ohne das ^ nicht umgewandelt)
- | -> "oder". Innerhalb dieses Teilsuchmusters gib es zwei verschiedene Möglichkeiten. Entweder trifft das ^ oder das [\n ] zu.
- [\n ] -> Zeichenklasse. Hier werden bestimmte Zeichen erlaubt oder verboten. In unserem Fall bedeutet [\n ], dass \n (also ein Zeilenumbruch und ein Leerzeichen erlaubt sind. Verbote werden innerhalb der Zeichenklasse mit ^ eingeleitet. z.b. [^plus] würde die Zeichenkette "plus" verbieten.
- ) -> Teilsuchmuster wird beendet \\1
- ( -> neues Teilsuchmuster beginnt \\2
- [\w]+? -> Zeichenklasse. Hier stellt \w jeden Buchstaben(a-z, A-Z) oder Zahl (0-9) dar plus den Unterstrich. Man könnte das auch der Zeichenklasse [a-zA-z0-9_] gleichsetzen. Das Pluszeichen nach der Zeichenklasse gibt an, dass mindestens ein Zeichen vorhanden sein muss oder bis zu unendlich viele, aber diesmal folgt ein Fragezeichen. Damit wird erzeugt, dass eine minimale Anzahl an Zeichen gesucht wird. mehr...
- :// -> Dies ist eine reine Zeichenfolge, die erfüllt werden muss. Man erkennt bereits, dass es dass :// aus http://domain ist.
- [\w\#$%&~/.\-;:=,?@\[\]+]* -> Die nächste Zeichenklasse. Der Stern am Ende gibt im Gegensatz zum Plus an, dass auch keines der Zeichen in den eckigen Klammern folgen kann. Deswegen wird auch aus http:// in phpBB ein Link. Ob das sinnvoll ist, sei mal dahin gestellt.
- \w -> jeder Buchstabe (a-z, A-Z) oder Zahl (0-9) plus den Unterstrich
- \# -> Im Gegensatz zu anderen Stellen, muss man hier aufpassen. Das Backslash stellt hier diesmal nicht wie bei \w einen speziellen Typ dar, sondern das Rautezeichen wird escaped. Das wurde gemacht, weil das Rautzeichen ja als Start- und Endmarkierung genutzt wird und ohne das Rautzeichen zu escapen würde die Zeichenkette an dieser Stelle abbrechen (= Fehler).
- $%&~/.\-;:=,?@ -> Diverse Zeichen sind erlaubt. Dollarzeichen, Prozent, Ampersand, ~, Slash, Punkt und nun folgt wieder ein \-. Das Minuszeichen ist normalerweise um eine neue character range anzugeben. Das wird z.B. verwendet, wenn man bestimmte Zeichen des Alphabets erlaubt: [a-cA-D] Hier werden die Buchstaben: a, b, c und A, B, C und D erlaubt. Daher müssen wir das Minuszeichen auch escapen, damit es in der Zeichenkette gesucht werden kann. (sonst wieder Fehler). Danach folgen Semikolon, Doppelpunkt, Undzeichen, Komma, Fragezeichen und das At-Zeichen. Dann folgen die eckigen Klammern (diese wurden wieder escaped \[ und \]). Und als letztes das Pluszeichen. Durch den Stern am Ende der Zeichenklasse wird jedes Zeichen erlaubt und es ist egal, wie oft es vorkommt. Soll heißen das wird natürlich auch ein Link: http://$$$&...=++[]]?. Störend empfinde ich die Tatsache, dass der letzte Punkt immer mit in den Link genommen wird. So werden Links am Ende eines Satzes leider zu falschen Links: www.phpbb.de/download.php.
- ]* -> Das Ende der Zeichenklasse. Der Stern sagt wie gesagt aus, dass keines oder bis zu unendlich viele Zeichen erlaubt sind.
- ) -> Das zweite Teilsuchmuster wird beendet \\2
- # -> Das Rautezeichen ist unsere Endmarkierung
- i -> Buchstaben nach der Endmarkerung sind Modifikatoren. Sie erlauben und verbieten zusätzlich. i erlaubt Groß- und Kleinbuchstaben. Das Verhältnis zwischen \w und i ist mir nicht ganz bekannt.
- s -> Damit wird der Punkt und Zeilenumbrüche erlaubt. Das Verhältnis zu \n und dem einfachen erlauben des Punktes in einer Zeichenklasse sind mir auch nicht bekannt
- " -> Suchmuster endet
- " -> Suchmuster beginnt
- \\1<a href=\"\\2\" target=\"_blank\">\\2</a> -> Ersatz. Die Teilsuchmuster werden hier nun in einen HTML-Tag eingesetzt. Das erste Teilsuchmuster war übrigens wichtig dafür, dass Links nur dann ersetzt werden, wenn ein Leerzeichen oder ein Zeilenumbruch davor steht. Denn wenn man einen Link in einem Tag einschließt http:// oder direkt davor ein anderes Zeichen steht, dann wird er nicht umgewandelt. Leider auch nicht, wenn er in einer Klammer steht (http://) oder ähnliches.
- " -> Suchmuster endet
- $ret -> In dieser Variable wird nach dem "Suchmuster" gesucht und im Fall eines Treffers mit "Ersatz" ersetzt. $ret ist übrigens der Text in einem Beitrag
Dinge, die mir nicht ganz klar sind, habe ich fett geschrieben.
Gruß