はじめに
正規表現で最短マッチというのがあるが、いくつかサンプルで動作を見ながら、どういう使い方をするのか確認してみよう。
内容
str = "ああああ「あ」い「うう」ええ「おおお」かかか"
このような文字列の中から、括弧で囲まれた部分のみ抽出したい(つまり、「あ」「うう」「おおお」の3ヶ所を抽出したい)場合、最短マッチを利用する事になります。
その前に、簡単な動きから確認してみよう。
+は、1文字以上でマッチするため、この例ではマッチしません。
str = "ああああ「」"
puts str.scan(/「.+」/)
=>マッチしない
*****は、0文字以上でマッチするため、この例ではマッチします。
str = "ああああ「」"
puts str.scan(/「.*」/)
=>「」
次の場合はどうだろうか
あの文字が1文字あるためマッチします。
str = "ああああ「あ」"
puts str.scan(/「.+」/)
=>「あ」
こちらも、あの文字が0文字あるためマッチします。結果的に同じです。
str = "ああああ「あ」"
puts str.scan(/「.*」/)
=>「あ」
少し、本題に入ります
この例だと、最初に出現した、**「と、最終に出現した、」**で囲まれた部分でマッチしてしまいます。やりたい事はこれではありません。
str = "ああああ「あ」い「うう」ええ「おおお」かかか"
puts str.scan(/「.+」/)
=>「あ」い「うう」ええ「おおお」
で、どうすればいいか
**?**を付加すれば、最短マッチをしてくれるようになります。
str = "ああああ「あ」い「うう」ええ「おおお」かかか"
puts str.scan(/「.+?」/)
=>「あ」「うう」「おおお」
おめでとうございます。
こうすればどうなる?
+の代わりに、*****にしても結果的には同じではありますが・・・
str = "ああああ「あ」い「うう」ええ「おおお」かかか"
puts str.scan(/「.*?」/)
=>「あ」「うう」「おおお」
**「」をマッチさせたいか、させたくないかで、+と***を使い分ける事になります。
**「」**をマッチさせたくない場合は、1文字以上でマッチする、+を使います。
str = "ああああ「あ」い「うう」ええ「おおお」かかか「」"
puts str.scan(/「.+?」/)
=>「あ」「うう」「おおお」
**「」をマッチさせたい場合は、0文字以上でマッチする、***を使います。
str = "ああああ「あ」い「うう」ええ「おおお」かかか「」"
puts str.scan(/「.*?」/)
=>「あ」「うう」「おおお」「」
C'est fini