Ограничаване на алчността в регулярните изрази в PHP
Регулярните изрази по подразбиране са алчни. Това означава, че те захващат максимално възможното количество символи.
Нека разгледаме пример. Да предположим, че имаме следния низ:
<?php
$str = 'aeeex zzz x kkk';
?>
Да предположим, че в този низ искаме да намерим подниза
'aeeex' по следния шаблон: буква
'a', следван от произволен символ един или повече
пъти, следван от буква 'x'.
<?php
$res = preg_replace('#a.+x#', '!', $str);
?>
Очакваме, че в променливата в резултат
ще бъде записан низът '! zzz x kkk'. Обаче,
това не е така - в променливата попада низът
'! kkk'.
Цялата работа е в това, че нашето регулярно изразяване търси всички
символи от буквата 'a' до буквата 'x'.
Но в нашия низ има две букви 'x'. Поради
алчността се оказва, че регулярният израз търси до
последната буква 'x', като по този начин захваща
не това, което очаквахме.
Разбира се, често това поведение е точно това, от което се нуждаем. Но конкретно в този случай бихме искали да деактивираме алчността и да кажем на регулярния израз да търси до първата буква 'x'.
За да ограничите алчността, трябва да поставите въпросителен знак след оператора за повторение:
<?php
$res = preg_replace('#a.+?x#', '!', $str);
?>
Алчността може да бъде ограничена за всички оператори
за повторение, ето така: *?, ??
и {}?.
Даден е низ:
<?php
$str = 'aba accca azzza wwwwa';
?>
Напишете регулярен израз, който ще намери всички низове,
по чиито краища стоят букви 'a',
и ще замени всеки от тях с '!'. Между
буквите a може да има произволен символ (освен
'a').