Rubyの正規表現で対応する括弧を考慮していい具合にマッチさせる
1.9以降に搭載された正規表現エンジン(oniguruma, onigumo)では
(?<name>式)
によってマッチした式
部分に名前(ここではname
)を付けることができ、- それにマッチした内容を後方参照
\k<name>
で参照でき、 - また
\g<name>
でその式を再帰的に呼び出すことができる
これを使えば、括弧のペアを対応させた上でマッチさせることができる。
たとえば次の例ではLispのシングルクォーテーション記法をquote
関数の呼び出しに変換する。
regexp = /'(?<paren>\((?:[^()]|\g<paren>)*\))/ replace = '(quote \k<paren>)' # 1段 "'(+ 1 2)".match(regexp) #=> #<MatchData "'(+ 1 2)" paren:"(+ 1 2)"> "'(+ 1 2)".gsub(regexp, replace) #=> "(quote (+ 1 2))" # 2段 "'(+ 1 (+ 2 3))".match(regexp) #=> #<MatchData "'(+ 1 (+ 2 3))" paren:"(+ 1 (+ 2 3))"> "'(+ 1 (+ 2 3))".gsub(regexp, replace) #=> "(quote (+ 1 (+ 2 3)))" # 並んでてもOK "'(+ (+ 0 1) (+ 2 3))".match(regexp) #=> #<MatchData "'(+ (+ 0 1) (+ 2 3))" paren:"(+ (+ 0 1) (+ 2 3))"> # 括弧の対応がとれていない場合にはマッチしない "'(+ 1 2))".match(regexp) #=> nil