「string#matchが返すのは配列じゃなかったよ」|ただいまRubyの修行中です
はじめに
ちょこちょこと、String#matchで正規表現とグループを使って文字列の切り出しをしていたのです。
でも、$1とか$2だと処理しずらいな~と思い、ちらっとサンプルコードを見たところ
s = "<hello> <world>" if md = s.match(/<(\w+)>/) puts md[0] puts md[1] end
「$1とか$2じゃなくて配列を返すのか~」と安易に判断してArray#mapを繋げてみたところ…
puts "123,456,789,987".match(/(\d+),(\d+)/).map(&:to_i)
mapメソッドなんて無いと怒られましたっ
code.rb:3:in `<main>': undefined method `map' for #<MatchData "123,456" 1:"123" 2:"456"> (NoMethodError)
メッセージを見るとMatchDataクラスのオブジェクトが返って来てる。
MatchDataクラスとは?
Ruby 2.1.0 リファレンスマニュアル class MatchData
正規表現のマッチに関する情報を扱うためのクラスで、配列のように[]でも値が取得できるように定義されています。
折角なので、面白そうなメソッドが無いかリファレンスを眺めて、どんなメソッドがあるのか個人用に一覧化してみたり。
メソッド | 戻り値 | 説明 |
---|---|---|
マッチした文字列とその前後の取得 | ||
to_s | String | マッチした文字列全体を返す |
pre_match | String | マッチした部分より前の文字列を返す($`と同じ) |
post_match | String | マッチした部分より後ろの文字列を返す($'と同じ) |
グループにマッチした文字列の取得 | ||
captures | [String] | $1, $2,...を格納した配列を返す。 |
to_a | [String] | $&, $1, $2,...を格納した配列を返す。 |
values_at(*index) | [String] | 正規表現中のn番目の括弧にマッチした部分文字列の配列を返す(0番目は$&) |
マッチした文字列の位置取得 | ||
begin(n) | Fixnum | n番目の部分文字列先頭のオフセット。マッチしていなければnil。 |
end(n) | Fixnum | n番目の部分文字列終端のオフセット。マッチしていなければnil。 |
offset(n) | [Fixnum] | n番目の部分文字列のオフセットの配列[start,end]を返す。 |
比較結果の情報取得 | ||
regexp | Regexp | 自身の元になった正規表現オブジェクトを返す |
string | String | マッチ対象になった文字列の複製を返す |
names | [Array] | 名前付きキャプチャの名前を文字列配列で返す(=self.regexp.names) |
length/size | Fixnum | 部分文字列の数を返す(=self.to_a.size,$&も含も含まれると言うこと) |
values_at(*index)メソッドなんかは面白いかも。
irb(main):001:0> "2014,1,24".match(/(\d+),(\d+),(\d+)/).values_at(2,3,1).join("/") => "1/24/2014"