PHP正規表現における非キャプチャグループ
括弧 () は2つの機能を持っています -
文字のグルーピングとキャプチャ(カプチャ)グループとしての機能です。
では、グルーピングは必要だけどキャプチャはしたくない場合はどうすればよいでしょうか?
この問題を解決するために、特別な
非キャプチャグループ (?: )
が考案されました - これらはグルーピングしますが、キャプチャしません。
例
次の例では、最初の括弧はグルーピングのために、 2番目の括弧はキャプチャのために必要です。 しかし、どちらの括弧もデータをキャプチャしてしまいます:
<?php
$str = 'abab123';
$reg = '#(ab)+([1-9]+)#';
preg_match_all($reg, $str, $res);
?>
結果、キャプチャグループには以下の内容が入ります:
<?php
var_dump($res[0]); // 'abab123'を出力
var_dump($res[1]); // 'ab'を出力
var_dump($res[2]); // '123'を出力
?>
例
最初の括弧のペアがグルーピングのみを行い、 キャプチャしないように変更してみましょう:
<?php
$str = 'abab123';
$reg = '#(?:ab)+([1-9]+)#';
preg_match_all($reg, $str, $res);
?>
結果、最初のキャプチャグループには数字が入ります:
<?php
var_dump($res[1]); // '123'を出力
?>
実践問題
任意の数の $@ のペアによって2つの部分に分割された
部分文字列があります:
<?php
$str = 'aaa$@bbb aaa$@$@bbb aaa$@$@$@bbb';
?>
そのような各部分文字列を見つけ、 見つかった各部分文字列について、 区切り文字の前にある部分を最初のキャプチャグループに、 区切り文字の後にある部分を2番目のキャプチャグループに入れてください。