@knowledge9876

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

正規表現の強欲の違いについて

正規表現の強欲と無欲の違いがよくわからないです。
?
??
?+
これらです。
実際の違いが出る実例がないとわからない状況です。
どんな場合になりますでしょうか?

量指定子

欲張り

?       一回または零回
*       零回以上
+       一回以上
{n,m}   n回以上m回以下
{n,}    n回以上
{,n}    零回以上n回以下 ({0,n})
{n}     n回

無欲

??      一回または零回
*?      零回以上
+?      一回以上
{n,m}?  n回以上m回以下
{n,}?   n回以上
{,n}?   零回以上n回以下 (== {0,n}?)

強欲 (欲張りで、繰り返しに成功した後は回数を減らすような後退再試行をしない)

?+      一回または零回
*+      零回以上
++      一回以上
0 likes

1Answer

欲張りと無欲の違いは、マッチの仕方が2通り以上あるとき、最長のものを選ぶか最短のものを選ぶかの違いです。

検索対象の文字列を 1<foo>2<bar>3<baz>4 とすると、

  • 欲張りな量指定子を使ったパターン <.*><foo>2<bar>3<baz> にマッチします。
  • 無欲な量指定子を使ったパターン <.*?><foo> にマッチします。

強欲は欲張りに似ていますが、最長マッチが見つかった後はバックトラック(再試行)しません。

上記の例 <.*> で、欲張りな量指定子はマッチするまでに実は再試行を行っています。パターンを頭から順に処理していくと:

  1. パターンの < が検索対象文字列2文字目の < にマッチ。
  2. パターンの .* が続きの foo>2<bar>3<baz>4 にマッチ。
  3. パターンの > はマッチしない( 続きに > がないため)→直前の量指定子の繰り返し回数を減らして再試行↓
  4. パターンの .* が続きの foo>2<bar>3<baz> にマッチ。
  5. パターンの > はマッチしない( 続きに > がないため)→直前の量指定子の繰り返し回数を減らして再試行↓
  6. パターンの .* が続きの foo>2<bar>3<baz にマッチ。
  7. パターンの > が続きの > にマッチ。
  8. パターン末尾までマッチしたのでマッチ成功。

このように、欲張りな量指定子はまず最大の繰り返し回数でマッチを試み、パターン全体のマッチが失敗するようなら繰り返しを減らします。

一方、強欲な量指定子は再試行せずにマッチを失敗させます。 パターンが <.*+> だったとしたら上の手順の3番目で再試行せずに打ち切られるということです。

4Like

Comments

  1. @knowledge9876

    Questioner

    勉強になりました。ありがとうございます。次回の質問もよろしくお願いいたします。

Your answer might help someone💌