Rubyで「正規表現でマッチした部分を抽出する」を書いたのだが、なんかしょぼかったので復習
Rubyで「文字列から正規表現にマッチする部分だけぶっこ抜く」ってのをやろうとしてこんな風に書いたのだけど、もっとシンプルに書けるはずだったので復習。
str = 'http://instagram.com/p/hoge/' #hogeを抜き出したい m = str.match(/http:\/\/instagram.com\/p\/(.+?)\//) id = m[1] puts id
まず、http:\/\/みたいにエスケープしまくるのが面倒。%rを使えば完結に書けた。%rは直後に来る文字を正規表現のデリミタとする。今回の例だと/が何度も出てくるので、/以外の文字をデリミタにすれば、何度もエスケープする必要がなくなる。
%r{http://instagram.com/p/(.+?)/}
デリミタにする文字は何でもよい。なので、これも等価。
%r!http://instagram.com/p/(.+?)/!
次にm=の部分。変数に代入する必要はない。str.match(%r{http://instagram.com/p/(.+?)/})はマッチするとMatchDataオブジェクトを返す。[]はMatchDataオブジェクトのメソッドなので、普通に繋げて書ける。結局、最初のコードは以下のように書ける。
str = 'http://instagram.com/p/hoge/' id = str.match(%r{http://instagram.com/p/(.+?)/})[1] puts id # p (str.match(%r{http://instagram.com/p/(.+?)/})).class => MatchData
ちなみに、上記ではmatchメソッドを使ったが、=~演算子を使っても書ける。ただし、その場合マッチした結果返ってくる値はMatchDataオブジェクトではなく、マッチした部分の位置になる。MatchDataオブジェクトはどこにセットされているかというと、$~という変数にセットされている。
str = 'http://instagram.com/p/hoge/' str =~ %r{http://instagram.com/p/(.+?)/} id = $~[1] puts id # p (str =~ %r{http://instagram.com/p/(.+?)/}) => 0 # p $~.class => MatchData
正規表現苦手意識克服したい