トップページに戻る    次の正規表現パズルへ    前の正規表現パズルへ

11-2 括弧問題(田中哲スペシャル)

正規表現パズル

行頭直後の開き括弧から、対応する閉じ括弧まで中身を含めて検索する。
括弧のネストは許可する。

擬似括弧として開き括弧をS、閉じ括弧をEとする。

詳説正規表現2版の423ページ
詳説正規表現3版の431ページ
を参考にさせていただきました。

7-9 行頭にある最初の擬似括弧の中身を検索のPHPで田中哲スペシャルを使う解です。


対象データ

S 1+2+3 E
S 1+2+S 3+4 E*5 E+1+2
S 1+2+S 3+4 E*5 E+S 1+2 E*3
S S S 1+2 E *2 E*3 E+ S1+2 E
1+2+S 1*5 E
S S E S E E
S S S E E S E E


ソース

<?php
define('ConstRegex','^(?<rec>S([^SE]|\g<rec>)*E)');
$arr = array();
$arr[] = 'S 1+2+3 E';
$arr[] = 'S 1+2+S 3+4 E*5 E+1+2';
$arr[] = 'S 1+2+S 3+4 E*5 E+S 1+2 E*3';
$arr[] = 'S S S 1+2 E *2 E*3 E+ S1+2 E';
$arr[] = '1+2+S 1*5 E';
$arr[] = 'S S E S E E';
$arr[] = 'S S S E E S E E';

echo 'Pattern ' . ConstRegex;

for ($i = 0; $i <= count($arr)-1; $i++) {
    $willOut = "\nLine" . ($i+1) . ' ' . $arr[$i];

    if (preg_match('/' . ConstRegex . '/',$arr[$i],$matchArr))
        $willOut .= ' matchs ' . $matchArr[0];
    else
        $willOut .= ' no match';

    echo $willOut;
}


実行結果

Pattern ^S[^SE]*(?<rec>S[^SE]*\g<rec>E[^SE]*\g<rec>|)E
Line1 S 1+2+3 E matchs S 1+2+3 E
Line2 S 1+2+S 3+4 E*5 E+1+2 matchs S 1+2+S 3+4 E*5 E
Line3 S 1+2+S 3+4 E*5 E+S 1+2 E*3 matchs S 1+2+S 3+4 E*5 E
Line4 S S S 1+2 E *2 E*3 E+ S1+2 E matchs S S S 1+2 E *2 E*3 E
Line5 1+2+S 1*5 E no match
Line6 S S E S E E matchs S S E S E E
Line7 S S S E E S E E matchs S S S E E S E E


解説

PHP5の正規表現では鬼車を使えます。