PHP/MySQL - Reguläre Ausdrücke - Gierig und ungierig
1. Die Abschnitte
- Einführung
- Befehle
- Grundlagen Teil 1
- Grundlagen Teil 2
- Der Backslash (\)
- Klammern
- Gierig und ungierig
- Rückbezüge
- Beispiele
2. Greedy und ungreedy
... sind die korrekten englischen Bezeichnungen für ein Verhalten von Regulären Ausdrücken, dass ich hier einfach mal wortwörtlich übersetzt habe. Wobei sich ungierig ziemlich komisch anhört. Was soll's. Wir haben ja auch so schöne Kreationen wie unabsteigbar oder unkaputtbar.
3. Greedy
Um was geht es denn nun? "Greedy", also "gierig", bedeutet, dass wenn man nach einem regulären Ausdruck sucht, alles gekrallt wird, was nicht niet- und nagelfest ist, solange es in das Muster passt. Greifen wir mal auf das Beispiel aus dem letzten Abschnitt "Klammern" zurück. Da haben wir schön jeden einzelnen Link erfasst. Aber warum? Weil sie alle in verschiedenen Zeilen standen!
Ein feiner Unterschied
Schaut euch mal an, was bei folgendem Beispiel passiert. Das mit dem <a name="...">
habe ich nur aus Platzgründen
gemacht.
<?php
$result = '<a name="bla">bla</a> oder <a name="blubb">blubb</a>
oder <a name="laber">laber</a>
und noch etliche weitere';
preg_match_all ("|<a[^>]*>.+\w</a>|i",$result, $links);
print_r($links);
?>
Da bekommt ihr folgendes Ergebnis:
Array
(
[0] => Array
(
[0] => <a name="bla">bla</a> oder <a name="blubb">blubb</a>
[1] => <a name="laber">laber</a>
)
)
Und dieses Verhalten nennt man gierig. Das kann man wunderbar daran erkennen, dass der erste Treffer zwei Links enthält. Das liegt
daran, dass alle preg
-Varianten nach einem Zeilenumbruch eine Pause einlegen und dann von vorne anfangen. Wenn man
nun zusätzlich mit dem Modifier s
arbeitet, so wird die komplette Zeichenkette als Einheit genommen und man
erhält nur noch einen Treffer mit drei Links. Probiert es mal aus.
Tipp
Spielt mal ein wenig mit den Modifiern s
und m
sowie unterschiedlichen Klammern und
PREG_SET_ORDER
. Dann wird euch dieses Verhalten genauer vor Augen gehalten.
<?php
preg_match_all ("|<a[^>]*>.+\w</a>|si",$result, $links);
preg_match_all ("|<a[^>]*>(.+\w)</a>|mi",$result, $links);
preg_match_all ("|(<a[^>]*>)(.+\w)(</a>)|si",$result, $links,
PREG_SET_ORDER);
?>
4. Ungreedy
Um diesen verhalten zu unterbinden, muss man einfach nur den Modifier U
setzen. Und bitte groß schreiben!
Ungreedy oder ungierig bedeutet einfach gesagt, dass bei jedem Treffer neu angefangen wird. Damit wird
jeder Link separat erfasst, auch wenn man mit dem Modifier s
arbeitet. So bringt folgender Code
<?php
preg_match_all ("|<a[^>]*>(.+\w)</a>|Usi",
$result, $links, PREG_SET_ORDER);
?>
dieses Ergebnis:
Array
(
[0] => Array
(
[0] => <a name="bla">bla</a>
[1] => bla
)
[1] => Array
(
[0] => <a name="blubb">blubb</a>
[1] => blubb
)
[2] => Array
(
[0] => <a name="laber">laber</a>
[1] => laber
)
)
zurück zum vorherigen Abschnitt weiter zum nächsten Abschnitt