PHPの正規表現におけるキャプチャグループ
キャプチャグループの内容は、置換文字列だけでなく、正規表現自体の中でも利用可能です。 何かをキャプチャグループに保存し、その同じ正規表現内で「ここにはそのキャプチャグループの内容が入るべきだ」と指定することができます。
キャプチャグループの内容は、バックスラッシュに続く番号で参照できます。
例えば、0番目のキャプチャグループは \0 のように、
1番目のキャプチャグループは \1 のように、
2番目のキャプチャグループは \2 のように参照できます。
おそらく、上記の説明はまだ非常に曖昧に感じられることでしょう。 それは当然です。キャプチャグループの参照は正規表現の中でも最も理解しにくい部分の一つです。 それでは、例を通して理解を深めていきましょう。
例
次のような文字列があるとします:
<?php
$str = 'aa bb cd ef';
?>
この文字列から、同じ文字が連続して2回現れるすべての部分を探してみましょう。 問題を解決するために、任意の文字を探し、それをキャプチャグループに保存し、 その次の文字がそのキャプチャグループの内容と一致するかどうかを確認します:
<?php
$res = preg_replace('#([a-z])\1#', '!', $str);
?>
結果、変数には以下の内容が格納されます:
'! ! cd ef'
例
次のような文字列があるとします:
<?php
$str = 'asxca buzxb csgd';
?>
この文字列から、最初と最後の文字が同じであるすべての単語を探してみましょう。 この問題を解決するために、次のパターンを書きます:文字、その後に1文字以上の文字が続き、最後に最初の文字と同じ文字:
<?php
$res = preg_replace('#([a-z])[a-z]+\1#', '!', $str);
?>
結果、変数には以下の内容が格納されます:
'! ! csgd'
例
\1 の代わりに \g1 と書くこともできます:
<?php
$res = preg_replace('#([a-z])[a-z]+\g1#', '!', $str);
?>
例
\g{1} と書くこともできます:
<?php
$res = preg_replace('#([a-z])[a-z]+\g{1}#', '!', $str);
?>
例
波括弧の中に負の数を指定することができます。 この場合、キャプチャグループは後ろから数えられます:
<?php
$res = preg_replace('#([a-z])([a-z])\g{-2}#', '!', $str);
?>
実践問題
以下の文字列が与えられます:
<?php
$str = 'aaa bbb ccc xyz';
?>
同じ文字が3回連続して現れるすべての部分文字列を見つけてください。
以下の文字列が与えられます:
<?php
$str = 'a aa aaa abab bbbb';
?>
同じ文字が2回以上連続して現れるすべての部分文字列を見つけてください。
以下の文字列が与えられます:
<?php
$str = 'aaa aaa bbb bbb ccc ddd';
?>
同じ単語が2回連続して現れるすべての部分文字列を見つけてください。