Beperking van gulzigheid in regex in PHP
Reguliere expressies zijn standaard gulzig. Dit betekent dat ze het maximaal mogelijke aantal tekens vastleggen.
Laten we dit met een voorbeeld bekijken. Stel dat we de volgende string hebben:
<?php
$str = 'aeeex zzz x kkk';
?>
Stel dat we in deze string de substring
'aeeex' willen vinden volgens het volgende patroon: letter
'a', dan elk teken een of meer keer,
dan letter 'x'.
<?php
$res = preg_replace('#a.+x#', '!', $str);
?>
We verwachten dat als resultaat in de variabele
de string '! zzz x kkk' wordt geschreven. Echter,
dit is niet het geval - in de variabele komt de string
'! kkk' terecht.
De reden is dat onze regex alle tekens zoekt
van letter 'a' tot letter 'x'.
Maar in onze string staan twee letters 'x'. Door
de gulzigheid gebeurt het dat de regex tot
de allerlaatste 'x' zoekt, waardoor hij
iets vastlegt dat we niet verwachtten.
Natuurlijk is dit gedrag vaak wel wat we nodig hebben. Maar in dit specifieke geval zouden we de gulzigheid willen uitschakelen en de regex opdragen om tot de eerste 'x' te zoeken.
Om de gulzigheid te beperken, moet je na de herhalingsoperator een vraagteken plaatsen:
<?php
$res = preg_replace('#a.+?x#', '!', $str);
?>
Gulzigheid kan voor alle herhalingsoperatoren worden beperkt,
zoals volgt: *?, ??
en {}?.
Gegeven de string:
<?php
$str = 'aba accca azzza wwwwa';
?>
Schrijf een regex die alle strings vindt
waar aan de randen de letters 'a' staan,
en vervang elk ervan door '!'. Tussen
de letters a kan elk teken staan (behalve
'a').