正規表現ってあるじゃないですか。そうです。アレです。
とっても便利で、いろんな場面で役立つと思うんですが、ときどき最短マッチを使いたくなって「最短マッチってどう書くんだっけなぁ?」ってなってググることがあります(よね!)
通常、正規表現内で * とか + とか付けると、直前の表現の0回/1回以上の繰り返しを表しますが、この書き方だとできるだけ長い要素にマッチしようとします。大事なことなのでもう一度言います。できるだけ長い要素にマッチしようとするんです。
大抵はそれで構わないんですが、ときどきそれでは困るケースがあります。例えばこんなケースを考えてみましょう(あんまり良い例が思いつかない)。
このような場合、正規表現はおそらくこのような形になるでしょう。
$1に名前が、$2にニックネームが入りますよね。(a) の場合は何も問題ありません。ただ困ってしまうのが、名前と(ニックネーム)の間に半角or全角スペースが入っている (b) のような場合です。
半角or全角スペースはあったり無かったりなので [\s ]? としていますが、その前の (.+) ができるだけ長くマッチしようとするため、(b) の場合には半角or全角スペースの部分までマッチしてしまいます。。
そんなときには最短マッチを使うと便利です。今まで * とか + とか書いていたのを *? とか +? とか書くだけです。これだけで最短マッチになります!
(b) の場合にも、余計な半角or全角スペースを含まずに抽出することが出来ました。なるべく短くマッチしようとするため、半角or全角スペースの部分は [\s ]? がマッチするわけですー。
参考:正規表現 - Rubyリファレンスマニュアル
とっても便利で、いろんな場面で役立つと思うんですが、ときどき最短マッチを使いたくなって「最短マッチってどう書くんだっけなぁ?」ってなってググることがあります(よね!)
通常は最長マッチになる
通常、正規表現内で * とか + とか付けると、直前の表現の0回/1回以上の繰り返しを表しますが、この書き方だとできるだけ長い要素にマッチしようとします。大事なことなのでもう一度言います。できるだけ長い要素にマッチしようとするんです。
大抵はそれで構わないんですが、ときどきそれでは困るケースがあります。例えばこんなケースを考えてみましょう(あんまり良い例が思いつかない)。
・"名前(ニックネーム)"という形式
・名前と(ニックネーム)の間には半角or全角スペースがあったりもする
このような場合、正規表現はおそらくこのような形になるでしょう。
def split_name(name) if name =~ /^(.+)[\s ]?((.+))$/ [$1, $2] end end # (a) name_str = "佐々木達也(ささたつ)" p split_name(name_str) # ["佐々木達也", "ささたつ"] # (b) name_str = "佐々木達也 (ささたつ)" p split_name(name_str) # ["佐々木達也 ", "ささたつ"]
$1に名前が、$2にニックネームが入りますよね。(a) の場合は何も問題ありません。ただ困ってしまうのが、名前と(ニックネーム)の間に半角or全角スペースが入っている (b) のような場合です。
半角or全角スペースはあったり無かったりなので [\s ]? としていますが、その前の (.+) ができるだけ長くマッチしようとするため、(b) の場合には半角or全角スペースの部分までマッチしてしまいます。。
* とか + の後ろに ? を付けると最短マッチに
そんなときには最短マッチを使うと便利です。今まで * とか + とか書いていたのを *? とか +? とか書くだけです。これだけで最短マッチになります!
def split_name(name) if name =~ /^(.+?)[\s ]?((.+))$/ # ? を追加 [$1, $2] end end # (a) name_str = "佐々木達也(ささたつ)" p split_name(name_str) # ["佐々木達也", "ささたつ"] # (b) name_str = "佐々木達也 (ささたつ)" p split_name(name_str) # ["佐々木達也", "ささたつ"]
(b) の場合にも、余計な半角or全角スペースを含まずに抽出することが出来ました。なるべく短くマッチしようとするため、半角or全角スペースの部分は [\s ]? がマッチするわけですー。
参考:正規表現 - Rubyリファレンスマニュアル