Bye Bye Moore

PoCソルジャーな零細事業主が作業メモを残すブログ

compileメソッドを使って複雑に入り組んだ正規表現を記述する

Regex#compileは複雑な正規表現を記述する際大活躍するメソッドです
以下のような順で引数をとります

compile(string, option = nil, code = nil) 

このうち、optionを生かすと

r = Regexp.compile "ge.+pi", Regexp::MULTILINE
#=> /ge.+pi/m

str =  "hoge\nhuga\n\npiyo"
#=> "hoge\nhuga\n\npiyo"

p str.match(r)[0]
#=>"ge\nhuga\n\npi"

のように、通常なら\\mのようなリテラルを記述する所も或る程度可視性を向上させる事も可能です。

公式には、このメソッドを使った禍々しい記法が載ってます。
普通の発想なら制御構文で書きそうなもんですが。。。

r = Regexp.compile(<<'__REGEXP__'.strip, Regexp::EXTENDED)
(?<element> \g<stag> \g<content>* \g<etag> ){0}
(?<stag> < \g<name> \s* > ){0}
(?<name> [a-zA-Z_:]+ ){0}
(?<content> [^<&]+ (\g<element> | [^<&]+)* ){0}
(?<etag> </ \k<name+1> >){0}
\g<element>
__REGEXP__