7

私は次のテキストを持っています

tooooooooooooon

私が読んでいるこの本によると、?任意の量指定子の後に続くと、貪欲ではなくなります。

私の正規表現to*?nはまだ返されてtooooooooooooonいます。

返すtonべきじゃないですか。

理由はありますか?

4

5 に答える 5

46

正規表現は、実際に存在するテキストの断片にのみ一致できます。

部分文字列「ton」は文字列のどこにも存在しないため、一致の結果にはなりません。一致すると、元の文字列の部分文字列のみが返されます

編集:明確にするために、以下の文字列を使用している場合は、余分な「n」を使用します

toooooooonoooooon

この正規表現 (「o」を指定しない)

t.*n

次のものに一致します (「n」の前にできるだけ多くの文字)

toooooooonoooooon

しかし、正規表現

t.*?n

次のものにのみ一致します (「n」の前の文字はできるだけ少なくします)

toooooooon
于 2008-10-29T09:36:09.553 に答える
5

正規表現は常にマッチしようとします。

あなたの表現はこう言っています:

't' の後に *できるだけ少ない* 'o' が続き、その後に 'n' が続きます。

つまり、最後に「n」があり、式が到達しようとしているため、必要なすべての o が一致することを意味します。すべての o が一致することが、成功する唯一の可能性です。

于 2008-10-29T09:44:46.040 に答える
4

正規表現は、それらのすべてに一致しようとします。n に一致するすべての o よりも一致する 'o' が少なくないため、すべてが一致します。また、o* を使用しているからですか? o+の代わりに?o が存在する必要はありません。

例、Perl

$a = "toooooo";
$b = "toooooon";

if ($a =~ m/(to*?)/) {
        print $1,"\n";
}
if ($b =~ m/(to*?n)/) {
        print $1,"\n";
}

~>perl ex.pl
t
toooooon
于 2008-10-29T09:37:10.563 に答える
4

正規表現は常に一致するように最善を尽くします。/o*?/この場合に行う唯一のことは、パーサーをノードにバックトラックさせることで、パーサーを遅くすることです。のすべてのシングル'o'に1 回"tooooon"。通常のマッチングでは'o'、最初からできるだけ多くの s が必要です。と照合する次の要素は であり'n'、これは と照合されないため'o'、最小限の照合を使用しようとしてもほとんど意味がありません。実際、通常のマッチングが失敗すると、失敗するまでにかなりの時間がかかります。バックトラックするものがなくなるまで、すべて'o'の をバックトラックする必要があります。この場合、実際には maximal matching を使用します/to*+n/。の'o'できる限りのことをして、決して返してはくれません。これにより、失敗したときにすぐに失敗するようになります。

最小限の RE 成功:

'toooooon' ~~ /to*?n/

 うーん       
{t} マッチ [t]
[t] 一致 [o] 0 回
[t]<n> 一致しない [n] -> 再試行 [o]
[t]{o} [o] に 1 回一致
[t][o]<n> [n] の一致に失敗 -> 再試行 [o]
[t][o]{o} [o] に 2 回一致
[t][o][o]<n> 一致しない [n] -> 再試行 [o]

. . . .

[t][o][o][o][o]{o} [o] に 5 回一致
[t][o][o][o][o][o]<n> 一致しない [n] -> 再試行 [o]
[t][o][o][o][o][o]{o} [o] に 6 回一致
[t][o][o][o][o][o][o]{n}一致[n]

通常の RE 成功:

(注: 最大 RE についても同様)

'toooooon' ~~ /to*n/

 うーん       
{t} マッチ [t]
[t]{o}{o}{o}{o}{o}{o} マッチ [o] 6 回
[t][o][o][o][o][o][o]{n}一致[n]

最小限の RE の失敗:

'toooooo' ~~ /to*?n/

 あまりにも

. . . .

. . . .

[t][o][o][o][o]{o} [o] に 5 回一致
[t][o][o][o][o][o]<n> 一致しない [n] -> 再試行 [o]
[t][o][o][o][o][o]{o} [o] に 6 回一致
[t][o][o][o][o][o][o]<n> 一致しない [n] -> 再試行 [o]
[t][o][o][o][o][o][o]<o> 一致に失敗 [o] 7 回 -> 一致に失敗

通常の RE の失敗:

'toooooo' ~~ /to*n/

 あまりにも       
{t} マッチ [t]
[t]{o}{o}{o}{o}{o}{o} マッチ [o] 6 回
[t][o][o][o][o][o][o]<n> 一致しない [n] -> 再試行 [o]
[t][o][o][o][o][o] [o] に 5 回一致
[t][o][o][o][o][o]<n> 一致しない [n] -> 再試行 [o]

. . . .

[t][o] [o] 1回一致
[t][o]<o> 一致しない [n] -> 再試行 [o]
[t] 一致 [o] 0 回
[t]<n> 一致に失敗 [n] -> 一致に失敗

最大 RE の失敗:

'toooooo' ~~ /to*+n/

 あまりにも
{t} マッチ [t]
[t]{o}{o}{o}{o}{o}{o} マッチ [o] 6 回
[t][o][o][o][o][o][o]<n> 一致に失敗 [n] -> 一致に失敗
于 2008-10-30T02:01:39.127 に答える
2

検索している文字列 (いわば干し草の山) には、部分文字列 "ton" が含まれていません。

ただし、部分文字列「toooooooooon」が含まれています。

于 2008-10-29T09:35:08.180 に答える