Greediness-Einschränkung in Regex in PHP
Reguläre Ausdrücke sind standardmäßig gierig. Das bedeutet, dass sie die maximal mögliche Anzahl an Zeichen erfassen.
Lassen Sie uns das an einem Beispiel erläutern. Angenommen, wir haben folgende Zeichenkette:
<?php
$str = 'aeeex zzz x kkk';
?>
Angenommen, wir möchten in dieser Zeichenkette die Teilzeichenkette
'aeeex' nach folgendem Muster finden: Buchstabe
'a', dann ein beliebiges Zeichen ein- oder mehrmals,
dann der Buchstabe 'x'.
<?php
$res = preg_replace('#a.+x#', '!', $str);
?>
Wir erwarten, dass in die Variable als Ergebnis
die Zeichenkette '! zzz x kkk' geschrieben wird. Allerdings
ist dies nicht der Fall - in die Variable gelangt die Zeichenkette
'! kkk'.
Der Grund liegt darin, dass unser regulärer Ausdruck alle
Zeichen vom Buchstaben 'a' bis zum Buchstaben 'x' sucht.
Aber in unserer Zeichenkette gibt es zwei Buchstaben 'x'. Aufgrund
der Gierigkeit stellt sich heraus, dass der reguläre Ausdruck bis
zum letzten 'x' sucht und dabei nicht das erfasst, was wir erwartet haben.
Natürlich ist dieses Verhalten oft genau das, was wir brauchen. Aber in diesem speziellen Fall möchten wir die Gierigkeit aufheben und dem regulären Ausdruck sagen, dass er bis zum ersten 'x' suchen soll.
Um die Gierigkeit einzuschränken, muss nach dem Wiederholungsoperator ein Fragezeichen gesetzt werden:
<?php
$res = preg_replace('#a.+?x#', '!', $str);
?>
Die Gierigkeit kann bei allen Wiederholungsoperatoren
eingeschränkt werden, wie folgt: *?, ??
und {}?.
Gegeben sei die Zeichenkette:
<?php
$str = 'aba accca azzza wwwwa';
?>
Schreiben Sie einen regulären Ausdruck, der alle Zeichenketten findet,
an deren Rändern die Buchstaben 'a' stehen,
und jede davon durch '!' ersetzt. Zwischen
den Buchstaben a kann ein beliebiges Zeichen stehen (außer
'a').