文字の繰り返しを表す正規表現パターンの最長一致と最短一致

正規表現

正規表現では文字が繰り返されている箇所を検索するための、メタキャラクタ(メタ文字)が用意されています。
繰り返しを表すメタキャラクタには、「*」(アスタリスク)や「+」(プラス)などがあります。

文字の繰り返しを表すための主なメタキャラクタ
メタキャラクタ 説明
* 0回以上の繰り返しにマッチ
+ 1回以上の繰り返しにマッチ
? 0回または1回の出現にマッチ
{n} 指定した回数(ここではn回)の繰り返しにマッチ
{n,} 指定した回数(ここではn回)以上の繰り返しにマッチ
{n,m} 指定した回数の範囲(ここではn回以上m回以下)の繰り返しにマッチ

文字の繰り返しを表す正規表現のマッチには2通りあります。

できるだけ広い範囲にマッチする「最長一致」と呼ばれるものと、最長一致とは逆に、できるだけ狭い範囲にマッチする「最短一致」と呼ばれるものです。

今回は、正規表現で文字の繰り返しを指定して検索する際に適用される、最長一致と最短一致について紹介します。

最長一致と最短一致

正規表現で「*」や「+」などのメタキャラクタで繰り返しを指定すると、デフォルト(既定値)では「可能な限り大きい範囲にマッチ」します。これを「最長一致」または「最長マッチ」といいます。
正規表現には、上記の最長一致とは逆に「可能な限り小さい範囲にマッチ」する「最短一致(最短マッチ)」という指定方法が用意されています。

以下に1つ正規表現の例を示します。

正規表現パターン
「b.+e」
対象の文字列
「Abcde cdef」

対象の文字列に対して指定する正規表現パターンが、どのようにマッチするかを皆さんも考えてみてください。

最長一致と最短一致の解説

正規表現のパターン「b.+e」は、文字列「b」と、任意の文字列を表す繰り返しパターンの「.+」と、文字列「e」が組み合わされています。
ですので、「”b”+ 任意の文字が1回以上続く文字+”e”」と一致することになります。
検索対象の文字列「Abcde cdef」に対してマッチする形式は、次の2通りの結果が考えられます。

Abcde cdef
Abcde cdef

2文字目の「b」から5文字目の「e」までの一致と、2文字目の「b」から9文字目の「e」までが一致する形式です。

もうお分かりですね。

5文字目の「e」までの一致する前者は、いちばん短い範囲でマッチしています。それに対して9文字目の「e」までが一致する後者では、いちばん長い範囲でマッチしています。

正規表現では明示的に指定をしない限り、繰り返しのパターンは最長一致でマッチします。
ですので、正規表現パターンの「b.+e」で文字列「Abcde cdef」を検索した場合は、9文字目の「e」まで(Abcde cdef)がマッチング結果となります。

最長一致ではなく最短一致でマッチさせたい場合は、繰り返しで使用するメタキャラクタの最後に「?」を加えたパターンを指定します。

既に出てきている「*?」「+?」「??」「{num,}?」「{num, num}?」がそれにあたります。

「b.+e」を最短一致に変更するのであれば、「b.+?e」とすればよいことになります。
検索対象の文字列「Abcde cdef」に対して「b.+?e」で検索すると、5文字目の「e」まで(Abcde cdef)がマッチします。

最長一致を表す量指定子一覧

以下に最長一致を表す量指定子(メタキャラクタ)の一覧をまとめておきます。

メタキャラクタ 説明
* 0回以上の繰り返しにマッチ
+ 1回以上の繰り返しにマッチ
? 0回または1回の出現にマッチ
{n} 指定した回数(ここではn回)の繰り返しにマッチ
{n,} 指定した回数(ここではn回)以上の繰り返しにマッチ
{n,m} 指定した回数の範囲(ここではn回以上m回以下)の繰り返しにマッチ

最短一致を表す量指定子一覧

以下に最短一致を表す量指定子(メタキャラクタ)の一覧をまとめておきます。

メタキャラクタ 説明
*? 0回以上の繰り返しにマッチ
+? 1回以上の繰り返しにマッチ
?? 0回または1回の出現にマッチ
{n}? 指定した回数(ここではn回)の繰り返しにマッチ
{n,}? 指定した回数(ここではn回)以上の繰り返しにマッチ
{n,m}? 指定した回数の範囲(ここではn回以上m回以下)の繰り返しにマッチ