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

7-10 行頭にある最初の括弧の中身を検索

正規表現パズル

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

検索前


検索後


対象データ

(1+2+3)
(1+2+(3+4)*5)+1+2
(1+2+(3+4)*5)+(1+2)*3
(((1+2)*2)*3)+(1+2)
1+2+(1*5)
(((-3))*(-9))+(555)


正規表現

^\([^()]*(?<rec>\([^()]*\g<rec>\)[^()]*\g<rec>|)\)

別解

^(?<rec>\(([^()]|\g<rec>)*\))


解説

前問の擬似括弧を括弧に変換しました。

■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
Perlでは、別の正規表現で解決できるようです。
Perlで、バランスしたカッコの正規表現問題

・詳説正規表現の2版の318ページ
・詳説正規表現の3版の320ページ
にも書かれてます。


#Rubyでのソースと実行結果

wStr = '^(?<rec>\(([^()]|\g<rec>)*\))'
ConstRegex = Regexp.new(wStr)
hairetu = Array.new
hairetu.push('(1+2+3)')
hairetu.push('(1+2+(3+4)*5)+1+2')
hairetu.push('(1+2+(3+4)*5)+(1+2)*3')
hairetu.push('(((1+2)*2)*3)+(1+2)')
hairetu.push('1+2+(1*5)')
hairetu.push('(((-3))*(-9))+(555)')

puts "Pattern #{ConstRegex.source}"
for i in (0..hairetu.length-1)
    willOut = sprintf("Line%02d",i+1) + " #{hairetu[i]} "
    work = ConstRegex.match(hairetu[i]).to_a[0]
    if work then
        willOut += 'matchs ' + work
    else
        willOut += 'no match'
    end
    puts willOut
end

#実行結果
Pattern ^\([^()]*(?<rec>\([^()]*\g<rec>\)[^()]*\g<rec>|)\)
Line01 (1+2+3) matchs (1+2+3)
Line02 (1+2+(3+4)*5)+1+2 matchs (1+2+(3+4)*5)
Line03 (1+2+(3+4)*5)+(1+2)*3 matchs (1+2+(3+4)*5)
Line04 (((1+2)*2)*3)+(1+2) matchs (((1+2)*2)*3)
Line05 1+2+(1*5) no match
Line06 (((-3))*(-9))+(555) matchs (((-3))*(-9))