Rubyでの正規表現についての覚書

Ruby正規表現オブジェクトを作る方法は以下の三通り。

  1. /pattern/option
  2. %r{pattern}option
  3. Regexp.new('pattern', option)


通常扱うのは/pattern/option。所謂正規表現リテラルで、リテラル内には式展開を含める事ができる。

/hoge#{"foo"}/
# => /hogefoo/


ただし、optionには式展開を適用することができない。これはコンパイルエラーにもならないので注意が必要。

/hoge#{"foo"}/#{"ni"}
# => /hogefoo/ #式展開でくっつけたoption値が無視されている。

この問題は%r記法でも同様だった。
optionを動的にしたい場合はRegexp.newメソッドを使う。

Regexp.new("hoge", "i")
# => /hoge/i

Regexp.new("hoge", "o")
# => /hoge/i


……あれ?
どんな値を入れても何故かignore caseがオプションになってしまう。


Regexpのrdocを見て謎が解明。

第二引数が Fixnum であった場合、その値は

Regexp::IGNORECASE
Regexp::MULTILINE
Regexp::EXTENDED
論理和でなければなりません。

第二引数が Fixnum 以外であれば真偽値の指定として見なされ、真 (nil, false 以外)であれば Regexp::IGNORECASE の指定と同じになります。

第三引数が与えられた時には、$KCODE の値にかかわらず、指定された文字コードでマッチを行います。文字コードは $KCODE への代入と同様に文字列引数の最初の一文字で決定されます。

http://www.ruby-lang.org/ja/man/?cmd=view;name=Regexp


つまり、文字コードの取り扱いは第3引数で、第2引数はそれ以外のオプションになるようだ。今回は文字コードを動的に変えたかったので、最終的には以下のようなコードとなった。

charset = "o"
Regexp.new("hoge", nil, charset)
# => /hoge/o

charset = "u"
Regexp.new("hoge", Regexp::MULTILINE , charset)
# => /hoge/mu