正規表現でマッチした文字列だけすぐほしいとき

結論

マッチデータ全体がほしいとき
/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文字削減する効果もある。