phpの正規表現をみる中で「?:」という書き方の意味がわからなかったので調べました。
公式マニュアルのサブパターンに、下記のように記載があります。
開きカッコの後に "?:" を付けると、そのサブパターンは値のキャプチャを行わず、 キャプチャ用サブパターンの番号としてもカウントされません。
例えば、 文字列 "the white queen" に対し、次のパターンをマッチングさせてみましょう。
マニュアルにコード例が書いてあったものの、結果が載っていなかったので確認のために試してみました。
PHPをインタラクティブモードで実行して確認を行います。
$ php -a
?:をつけない場合
マニュアル通りの文字列とパターンでの実行結果です。
php > $text = 'the red king';
php > preg_match('/the ((red|white) (king|queen))/', $text, $m);
php > var_dump($m);
array(4) {
[0]=>
string(12) "the red king" // パターン全体にマッチした結果
[1]=>
string(8) "red king" // 外側の括弧にマッチした結果
[2]=>
string(3) "red" // 内側の1番目の括弧にマッチした結果
[3]=>
string(4) "king" // 内側の2番目の括弧にマッチした結果
}
?:をつける場合
こちらも同じくマニュアル通りです。
内側の1番目の開き括弧の後に "?:" を記載したため、こちらはキャプチャが行われておりません。
番号も0,1,2となっているため、下記の記述の通りになっているようです。
そのサブパターンは値のキャプチャを行わず、 キャプチャ用サブパターンの番号としてもカウントされません
php > $text = 'the red king';
php > preg_match('/the ((?:red|white) (king|queen))/', $text, $m2);
php > var_dump($m2);
array(3) {
[0]=>
string(12) "the red king" // パターン全体にマッチした結果
[1]=>
string(8) "red king" // 外側の括弧にマッチした結果
[2]=>
string(4) "king" // 内側の2番目の括弧にマッチした結果
}
もちろん内側の2つの括弧両方に"?:"を記載すると、両方ともキャプチャされなくなります。
php > preg_match('/the ((?:red|white) (?:king|queen))/', $text, $m3);
php > var_dump($m3);
array(2) {
[0]=>
string(12) "the red king"
[1]=>
string(8) "red king"
}