トップページに戻る
次の正規表現パズルへ
前の正規表現パズルへ
8-5 括弧問題(動的正規表現)
正規表現パズル
行頭直後の開き括弧から、対応する閉じ括弧まで中身を含めて検索する。
括弧のネストは許可する。
擬似括弧として開き括弧をS、閉じ括弧をEとする。
詳説正規表現2版の319ページ
詳説正規表現3版の322ページ
を参考にさせていただきました。
7-9 行頭にある最初の擬似括弧の中身を検索のPerlの動的正規表現を使う解です。
対象データ
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
正規表現
my $rec;
$rec = qr/(S[^SE]*(??{$rec})E[^SE]*(??{$rec})|)/;
m/^S[^SE]*$rec[^SE]*E/
解説
鬼車での解
^S[^SE]*(?<rec>S[^SE]*\g<rec>E[^SE]*\g<rec>|)E
を流用しています。
バランスしたカッコの正規表現問題
Perlでのソースと実行結果
@hairetu = ();
push(@hairetu,'S 1+2+3 E');
push(@hairetu,'S 1+2+S 3+4 E*5 E+1+2');
push(@hairetu,'S 1+2+S 3+4 E*5 E+S 1+2 E*3');
push(@hairetu,'S S S 1+2 E *2 E*3 E+ S1+2 E');
push(@hairetu,'1+2+S 1*5 E');
push(@hairetu,'S S E S E E');
push(@hairetu,'S S S E E S E E');
my $rec;
$rec = qr/(S[^SE]*(??{$rec})E[^SE]*(??{$rec})|)/;
for ($i=0; $i <= @hairetu-1; $i++) {
$LineNo = $i+1;
$willOut = "Line$LineNo $hairetu[$i] ";
if ($hairetu[$i] =~ m/^S[^SE]*$rec[^SE]*E/){
$willOut .= "matchs $&";
}
else{
$willOut .= 'no match'
}
print "$willOut\n";
}
#実行結果
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