正規表現オブジェクトの作り方と注意点
- /pattern/option
- %r{pattern}option
- Regexp.new('pattern', option)
一番利用頻度が高いのが/pattern/で、この場合patternには式展開を含める事ができる。
/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 の指定と同じになります。
http://www.ruby-lang.org/ja/man/?cmd=view;name=Regexp
わざわざ論理和とか計算したり長い定数名を書くらいならcaseで分けた方が早いと思う…。
そもそもoptionに式展開を含めたいと考えたのは文字コードを動的に変えたいからだった。
引き続きRegexpのrdocを読んで見ると以下のような記述を発見。
第三引数が与えられた時には、$KCODE の値にかかわらず、指定された文字コードでマッチを行います。文字コードは $KCODE への代入と同様に文字列引数の最初の一文字で決定されます。
http://www.ruby-lang.org/ja/man/?cmd=view;name=Regexp
と言うわけで以下のように使うと今回の目的は達成できる。
charset = "s" Regexp.new("hoge", nil, charset) # => /hoge/s charset = "u" Regexp.new("hoge", Regexp::MULTILINE , charset) # => /hoge/mu