Ograniczanie zachłanności w wyrażeniach regularnych w PHP

Wyrażenia regularne domyślnie są zachłanne. Oznacza to, że przechwytują maksymalną możliwą liczbę znaków.

Przeanalizujmy to na przykładzie. Załóżmy, że mamy taki ciąg znaków:

php<?php
  $str = 'aeeex zzz x kkk';
?>

Załóżmy, że w tym ciągu chcemy znaleźć podciąg 'aeeex' według następującego wzorca: litera 'a', następnie dowolny znak jeden lub więcej razy, następnie litera 'x'.

php<?php
  $res = preg_replace('#a.+x#', '!', $str);
?>

Oczekujemy, że do zmiennej w wyniku zostanie zapisany ciąg '! zzz x kkk'. Jednakże, tak nie jest - do zmiennej trafia ciąg '! kkk'.

Chodzi o to, że nasze wyrażenie regularne szuka wszystkich znaków od litery 'a' do litery 'x'. Ale w naszym ciągu są dwie litery 'x'. Z powodu zachłanności okazuje się, że wyrażenie regularne szuka do ostatniego 'x', tym samym przechwytując nie to, czego oczekiwaliśmy.

Oczywiście, często takie zachowanie jest właśnie tym, czego potrzebujemy. Ale konkretnie w tym przypadku chcielibyśmy wyłączyć zachłanność i powiedzieć wyrażeniu regularnemu, żeby szukało do pierwszego 'x'.

Aby ograniczyć zachłanność, należy po operatorze powtórzenia postawić znak zapytania:

php<?php
  $res = preg_replace('#a.+?x#', '!', $str);
?>

Zachłanność można ograniczać wszystkim operatorom powtórzeń, w ten sposób: *?, ?? i {}?.

Задание 1

Dany jest ciąg:

php<?php
  $str = 'aba accca azzza wwwwa';
?>

Napisz wyrażenie regularne, które znajdzie wszystkie ciągi na których końcach stoją litery 'a', i zastąpi każdy z nich na '!'. Między literami a może być dowolny znak (oprócz 'a').