Ruby の正規表現で名前付きキャプチャするときの注意

Ruby正規表現で名前付きキャプチャを行う時、Regexp#match ではなくて Regexp#=~ を使用することで『ローカル変数』として定義することも出来ます。

/(?<hour>\d{2}):(?<minus>\d{2}):(?<second>\d{2})/ =~ "11:22:33"
p hour   # => "11"
p minus  # => "22"
p second # => "33"

[左辺に正規表現リテラルを持ってこなければならない]

『ローカル変数』を定義するためには #=~ の左辺に正規表現リテラルを定義しなければなりません。 なので次のような書き方では『ローカル変数』は定義されません。

# 変数に定義したり
timep = /(?<hour>\d{2}):(?<minus>\d{2}):(?<second>\d{2})/
timep =~ "11:22:33"

# Regex.new でもローカル変数は定義されない
Regexp.new(/(?<hour>\d{2}):(?<minus>\d{2}):(?<second>\d{2})/) =~ "11:22:33"

[#{} を使用していない場合に限る]

正規表現リテラル内で #{} を使用していても『ローカル変数』は定義されません。

h_tag = "hour"
m_tag = "minus"
s_tag = "second"

# #{} を使用してる場合はローカル変数は定義されない
/(?<#{h_tag}>\d{2}):(?<#{m_tag}>\d{2}):(?<#{s_tag}>\d{2})/ =~ "11:22:33"