„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.