11

perl では、後に*a を追加しない限り、通常貪欲です?*ただし、グループに対して使用される場合、状況は異なるようです。私の質問は「なぜ」です。次の例を検討してください。

my $text = 'f fjfj ff';
my (@matches) = $text =~ m/((?:fj)*)/;
print "@matches\n";
# --> ""
@matches = $text =~ m/((?:fj)+)/;
print "@matches\n";
# --> "fjfj"

最初の一致では、perl は遅延して何も出力しませんが、2 番目の一致で示されているように、何かに一致した可能性があります。奇妙なことに、グループの内容が実際の文字で*はなく単なるものである場合、 の動作は期待どおり貪欲です。.

@matches = $text =~ m/((?:..)*)/;
print "@matches\n";
# --> 'f fjfj f'
  1. 注: 上記は perl 5.12 でテストされています。
  2. 注:グループ内にキャプチャまたは非キャプチャ括弧を使用するかどうかは関係ありません。
4

2 に答える 2

15

これは貪欲または怠惰な繰り返しの問題ではありません。可能な限り多くの "fj" の繰り返しに貪欲に一致しますが、(?:fj)*ゼロ繰り返しに一致します。string と照合しようとすると"f fjfj ff"、最初にゼロの位置 (最初の "f" の前) で照合が試みられます。位置 0 の "fj" と正常に一致できる最大回数は 0 であるため、パターンは空の文字列と正常に一致します。パターンは位置 0 で正常に一致したため、これで完了です。エンジンは、後の位置で一致を試行する理由がありません。

この話の教訓は、何にも一致させたくない場合を除いて、何にも一致しないパターンを書かないことです。

于 2013-07-09T00:10:31.430 に答える
7

Perl は、文字列のできるだけ早い段階 (一番左) に一致します。fj文字列の先頭にあるゼロの出現を照合することにより、最初の一致でそれを行うことができます

于 2013-07-09T00:11:05.027 に答える