Hatena::ブログ(Diary)

Lazy Technology

2007-11-08

[][]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


参考

no title

no title

2007-07-07

[][]正規表現オブジェクトの作り方と注意点

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

  1. /pattern/option
  2. %r{pattern}option
  3. 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


参考

no title

no title