- Home ›
- Ruby正規表現の使い方 ›
- 任意の文字と繰り返し(量指定子) ›
- HERE
欲張りなマッチと控え目なマッチ(量指定子?)
繰り返しを意味するメタ文字である「+」、「*」、「?」、「{min,max}」、「{num}」はなるべく長い文字列にマッチしようとします。
/a.+b/
上記の場合「a」で始まり任意の文字(改行除く)が1回以上続き「b」で終わる文字列にマッチします。これを「00a11b22b33b44」に対してマッチさせてみるとマッチする部分としては次の3つの候補があります。
00a11b22b33b44 00a11b22b33b44 00a11b22b33b44
マッチしたかどうかを考えるだけならば気にしなくても構いませんが、文字列の中のどの部分にマッチしたのかが必要になる時には、どの位置にマッチしたかを考えることは重要です。
このような時、繰り返しを表すメタ文字は一番長い文字列にマッチしようとします。つまりマッチする部分は次の箇所となります。
00a11b22b33b44
なお正規表現オブジェクトに対して「=~」メソッドがマッチした場合、マッチした部分が変数「$&」に格納されます。その為、マッチに成功した後で変数「$&」を参照すると対象の文字列の中のどの部分にマッチしたかを確認できます。
サンプルプログラム
では簡単なプログラムで確認して見ます。
#! ruby -Ku require "kconv" def check(str) if /a.+b/ =~ str then print(Kconv.tosjis("○") + str + "(" + $& + ")" + "¥n") else print(Kconv.tosjis("×") + str + "¥n") end end print(Kconv.tosjis("「a.+b」にマッチするかどうか¥n¥n")) check("00a11b22b33b44")
上記のプログラムを「test8-1.rb」として保存します。文字コードはUTF-8です。そして下記のように実行して下さい。
今回はマッチに成功した場合、マッチした部分も合わせて表示するようにしています。マッチ可能な最大の部分にマッチしていることが確認できます。
控え目なマッチ(最小量指定子)
デフォルトではマッチする範囲が最大になるようにマッチしますが、逆に最小になるようにマッチさせることも可能です。各メタ文字の後に「?」を付けて使用することで最小の部分にマッチするようになります。
+? *? ?? {min,max}? {min,}? {num}?
例として先ほどと同じように任意の文字を表すメタ文字「.」に対して1回以上繰り返しすメタ文字「+?」を使った場合で考えてみます。今回は最小量指定子付きとなっています。
/a.+?b/
上記の場合「a」で始まり任意の文字(改行除く)が1回以上続き「b」で終わる文字列にマッチします。これを「00a11b22b33b44」に対してマッチさせてみるとマッチする部分としては次の3つの候補があります。
00a11b22b33b44 00a11b22b33b44 00a11b22b33b44
今回は最小量指定子の「?」が付けられていますので、最も短い文字列にマッチしようとします。つまりマッチする部分は次の箇所となります。
00a11b22b33b44
サンプルプログラム
では簡単なプログラムで確認して見ます。
#! ruby -Ku require "kconv" def check(str) if /a.+?b/ =~ str then print(Kconv.tosjis("○") + str + "(" + $& + ")" + "¥n") else print(Kconv.tosjis("×") + str + "¥n") end end print(Kconv.tosjis("「a.+?b」にマッチするかどうか¥n¥n")) check("00a11b22b33b44")
上記のプログラムを「test8-2.rb」として保存します。文字コードはUTF-8です。そして下記のように実行して下さい。
マッチ可能な候補の中で最小の部分にマッチしていることが確認できます。
( Written by Tatsuo Ikura )