欲張りなマッチと控え目なマッチ(最小量指定子)

広告

前のページで簡単に確認しましたが、デフォルトでは最大限にマッチする範囲が多くなる位置でマッチします。これはメタ文字の「+」「*」「?」「{min,max}」のどれを使った場合でも同じです。

例として前のページで使用した任意の文字を表すメタ文字「.」に対して1回以上繰り返しすメタ文字「+」を使った場合で考えてみます。

/a.+b/

上記は「a」で始まり任意の文字が連続して続き「b」で終わる文字列にマッチします。このパターンを文字列「00a11b22b33b44」に対して適用すると次の位置でマッチする可能性があります。

00a11b22b33b44
00a11b22b33b44
00a11b22b33b44

この時、デフォルトではマッチする範囲が最大になるようにマッチするため、実際にマッチするのは次の位置になります。

00a11b22b33b44

このように最大の範囲でマッチすることを「欲張りなマッチ」と呼ばれています。

控え目なマッチ(最小量指定子)

広告

場合によってはマッチする範囲が最小になるようにマッチさせたい場合もあります。この時は各メタ文字の後に「?」を付けて使用します。

+?
*?
??
{min,max}?
{min,}?
{num}?

例として先ほどと同じように任意の文字を表すメタ文字「.」に対して1回以上繰り返しすメタ文字「+?」を使った場合で考えてみます。今回は最小量指定子付きとなっています。

/a.+?b/

上記は「a」で始まり任意の文字が連続して続き「b」で終わる文字列にマッチします。このパターンを文字列「00a11b22b33b44」に対して適用すると次の位置でマッチする可能性があります。

00a11b22b33b44
00a11b22b33b44
00a11b22b33b44

今回は最小量指定子が付いていますのでマッチする範囲が最小になるようにマッチするため、実際にマッチするのは次の位置になります。

00a11b22b33b44

このように最小の範囲でマッチすることを「控え目なマッチ(又は欲張りでないマッチ)」と呼ばれています。

サンプルプログラム

では簡単なプログラムで確認して見ます。

test8-1.pl

use strict;
use warnings;
use utf8;
binmode STDIN, ':encoding(cp932)';
binmode STDOUT, ':encoding(cp932)';
binmode STDERR, ':encoding(cp932)';

print "「P.+P」にマッチするかどうか¥n";

&check1("aP12Pa");
&check1("aP12P34Pa");
&check1("aP12P34P56Pa");

print "¥n「P.+?P」にマッチするかどうか¥n";

&check2("aP12Pa");
&check2("aP12P34Pa");
&check2("aP12P34P56Pa");

sub check1{
  my ($str) = @_;

  if ($str =~ /P.+P/){
    print "○:$str ($&)¥n";
  }else{
    print "×:$str¥n";
  }
}

sub check2{
  my ($str) = @_;

  if ($str =~ /P.+?P/){
    print "○:$str ($&)¥n";
  }else{
    print "×:$str¥n";
  }
}

上記を「test8-1.pl」の名前で保存します(文字コードはUTF-8です)。そしてコマンドプロンプトを起動し、プログラムを保存したディレクトリに移動してから次のように実行して下さい。

欲張りなマッチと控え目なマッチ(最小量指定子)

( Written by Tatsuo Ikura )