Bye Bye Moore

猫マンション建築の野望を胸に零細事業主として資本主義の荒波に漕ぎ出したアラサー男の技術メモ

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__