正規表現でマッチした文字列だけすぐほしいとき
結論
マッチデータ全体がほしいとき
/Regexp/=~str&&$&
部分がほしいときには
/Regexp/=~str&&$n
恥
マッチが失敗することを考慮するときにはto_a[1]を投げれば良かったんじゃないか
でも、短いしperlでも使える。よしとしよう。
$ perl -e 'print "abc"=~/./&&$&,"\n"' a $ perl -e 'print "abc"=~/d/&&$&,"\n"'
説明
まあ、通常は=~つかってマッチさせて$&と$数字でマッチした文字列を得ると思う。
irb(main):001:0> 'abc'=~/.(.)/ => 0 irb(main):002:0> $& => "ab" irb(main):003:0> $1 => "b"
注意:perlは=~が逆だと動かない。
正規表現オブジェクトにmatchメソッドを投げればMatchDataオブジェクトが返ってくるのでそれを利用することもできる。
irb(main):004:0> /.(.)/.match('abc') => #<MatchData:0x7ffa1ad4> irb(main):005:0> /.(.)/.match('abc')[0] => "ab" irb(main):006:0> /.(.)/.match('abc')[1] => "b"
ところが、マッチしない場合には[0],[1]はエラーとなってしまう。
irb(main):007:0> /d/.match('abc')[0] NoMethodError: undefined method `[]' for nil:NilClass from (irb):7 from :0 irb(main):008:0> /d(.)/.match('abc')[1] NoMethodError: undefined method `[]' for nil:NilClass from (irb):8 from :0
ここで[0]の時には返ってくるMatchDataオブジェクトにto_sを投げればnilにto_sに投げることと同じになるのでいけるのだが、[1]の時にはそうはいかない。
irb(main):009:0> /d/.match('abc').to_s => "" irb(main):010:0> /./.match('abc').to_s => "a"
そこで両方に共通な書き方がないかと考えてみたところ、考えついたのが /正規表現/=~マッチ対象&&$& だ。
別段大したことないのだが、記述量が小さいのがいける。(またかよ)
irb(main):011:0> /.(.)/=~'abc'&&$& => "ab" irb(main):012:0> /.(.)/=~'abc'&&$1 => "b" irb(main):013:0> /d(.)/=~'abc'&&$& => nil irb(main):014:0> /d(.)/=~'abc'&&$1 => nil
以上のように match().to_sよりも7文字削減する効果もある。