PHPにおける正規表現の貪欲さの制限
正規表現はデフォルトで貪欲です。 これは、可能な限り多くの文字を 捕捉することを意味します。
例で見てみましょう。次のような文字列が あるとします:
<?php
$str = 'aeeex zzz x kkk';
?>
この文字列から、次のパターンで部分文字列
'aeeex'を見つけたいとします:
文字'a'の後、任意の文字が1回以上、
次に文字'x'が続く。
<?php
$res = preg_replace('#a.+x#', '!', $str);
?>
結果、変数には文字列'! zzz x kkk'が
書き込まれることを期待します。しかし、
実際にはそうなりません - 変数に入るのは
文字列'! kkk'です。
理由は、この正規表現が文字'a'から
文字'x'までのすべての文字を
検索するためです。しかし、この文字列には
文字'x'が2つあります。
貪欲さのため、正規表現は最後のxまでを
検索し、結果として期待したものではない部分を
捕捉してしまうのです。
もちろん、多くの場合、この動作は必要です。 しかし、このケースでは、貪欲さを無効にして、 最初のxまでを検索するよう正規表現に 指示したいのです。
貪欲さを制限するには、繰り返し演算子の後に 疑問符を置きます:
<?php
$res = preg_replace('#a.+?x#', '!', $str);
?>
貪欲さはすべての繰り返し演算子に対して
制限できます。次のように:
*?, ??, そして{}?。
次の文字列が与えられています:
<?php
$str = 'aba accca azzza wwwwa';
?>
両端に文字'a'があるすべての文字列を
見つけ、それぞれを'!'に置き換える
正規表現を書いてください。文字aの間には
('a'を除く)任意の文字が存在します。