“non-greedy PHP regexp” – Du verstehst Bahnhof?
Ich versuche es allgemein verständlich zu erklären:
- Eine immer wieder auftretende Programmier-Aufgabe ist es, aus einem Textblock bestimmte Text-Teile zu extrahieren. Dazu ist ein Muster nötig, nach der die Software den Text analysiert.
- Beispieltext: “mein text: <b>fett</b> und nicht fett”
- Die Aufgabe: Extrahiere den Text der zwischen “<b>” und “</b>”
- Die Lösung ist der “reguläre Ausdruck” “<b>(.*)<\/b>”.
Dabei steht “(.*)” für irgendeinen Text.
Dieser reguläre Ausdruck wird z. B. in der PHP-Funktion preg_match verwendet:
preg_match(“/regulärer Ausdruck/”, “zu durchsuchender Text”, $treffer)
In der Variable $treffer steht dann das Suchergebnis. In unserem Beispiel ist das “fett”. - Soweit so gut.
Was aber, wenn im Text das Suchmuster mehrmals vorhanden ist?
Also der Text z. B. so ist: “mein text: <b>fett</b> und nicht fett. Hier aber noch <b>ein 2tes Mal fett</b> zum Ende” - Obiger preg_match mit dem regulären Ausdruck “<b>(.*)<\/b>” liefert den Text
“fett</b> und nicht fett. Hier aber noch <b>ein 2tes Mal fett”.
Denn das Suchmuster “<b>(.*)<\/b>” sucht den ersten “<b>” und den letzten “</b>”.
“(.*)” steht für “irgendeinen Text”. - Damit beide Texte extrahiert werden ist folgendes nötig:
Als Suchmuster “<b>(.*?)<\/b>” und preg_match_all
Das “?” macht den regulären Ausdruck “non-greedy”, greedy steht für “gierig” im Sinne dass der längstmögliche Text extrahiert werden soll.
non-greedy gibt die einzelnen Textstücke.
preg_match_all extrahiert die komplette Liste der Suchtreffer – im Unterschied zu preg_match, das nur den ersten Treffer extrahiert.