PHPの正規表現におけるキャプチャグループ

キャプチャグループの内容は、置換文字列だけでなく、正規表現自体の中でも利用可能です。 何かをキャプチャグループに保存し、その同じ正規表現内で「ここにはそのキャプチャグループの内容が入るべきだ」と指定することができます。

キャプチャグループの内容は、バックスラッシュに続く番号で参照できます。 例えば、0番目のキャプチャグループは \0 のように、 1番目のキャプチャグループは \1 のように、 2番目のキャプチャグループは \2 のように参照できます。

おそらく、上記の説明はまだ非常に曖昧に感じられることでしょう。 それは当然です。キャプチャグループの参照は正規表現の中でも最も理解しにくい部分の一つです。 それでは、例を通して理解を深めていきましょう。

例

次のような文字列があるとします:

php<?php
  $str = 'aa bb cd ef';
?>

この文字列から、同じ文字が連続して2回現れるすべての部分を探してみましょう。 問題を解決するために、任意の文字を探し、それをキャプチャグループに保存し、 その次の文字がそのキャプチャグループの内容と一致するかどうかを確認します:

php<?php
  $res = preg_replace('#([a-z])\1#', '!', $str);
?>

結果、変数には以下の内容が格納されます:

php'! ! cd ef'

例

次のような文字列があるとします:

php<?php
  $str = 'asxca buzxb csgd';
?>

この文字列から、最初と最後の文字が同じであるすべての単語を探してみましょう。 この問題を解決するために、次のパターンを書きます:文字、その後に1文字以上の文字が続き、最後に最初の文字と同じ文字:

php<?php
  $res = preg_replace('#([a-z])[a-z]+\1#', '!', $str);
?>

結果、変数には以下の内容が格納されます:

php'! ! csgd'

例

\1 の代わりに \g1 と書くこともできます:

php<?php
  $res = preg_replace('#([a-z])[a-z]+\g1#', '!', $str);
?>

例

\g{1} と書くこともできます:

php<?php
  $res = preg_replace('#([a-z])[a-z]+\g{1}#', '!', $str);
?>

例

波括弧の中に負の数を指定することができます。 この場合、キャプチャグループは後ろから数えられます:

php<?php
  $res = preg_replace('#([a-z])([a-z])\g{-2}#', '!', $str);
?>

実践問題

Задание 1

以下の文字列が与えられます:

php<?php
  $str = 'aaa bbb ccc xyz';
?>

同じ文字が3回連続して現れるすべての部分文字列を見つけてください。

Задание 2

以下の文字列が与えられます:

php<?php
  $str = 'a aa aaa abab bbbb';
?>

同じ文字が2回以上連続して現れるすべての部分文字列を見つけてください。

Задание 3

以下の文字列が与えられます:

php<?php
  $str = 'aaa aaa bbb bbb ccc ddd';
?>

同じ単語が2回連続して現れるすべての部分文字列を見つけてください。