5

正規表現の仕組みに関する基本的な質問:

私は次の式を持っています:[10]*1[10]*

これは一致し100ますか?

私の推論:
最初のオプション:[10]*「100」に一致し、次に文字列の最後に到達します=>一致しません。
2番目のオプション:[10]*は無視され、式は一致します。

些細なことを忘れているのでしょうか、それとも実際に正規表現エンジンに依存するのでしょうか?
(私は貪欲と貪欲ではないことについて何かを覚えていますが、それがこの場合に当てはまるかどうかはわかりません)

4

3 に答える 3

2

答えは、はい、一致します。なぜなら、正規表現パーサーは、式全体で一致を達成するために必要なだけ、各サブ式から多くを消費するからです。

あなたの場合、それを一致させるためにこれを行います:

  • 最初のもの[10]*はゼロ文字を消費します
  • その後、リテラルと一致します1
  • その後、最後[10]*は残りの入力を消費します


最後に、ここで質問する代わりに、regexpalで試してみて、自分の目で確かめてみませんか。

于 2012-10-25T19:37:36.623 に答える
2

正規表現エンジンはバックトラックを実行します。

エンジンはと一致しようとしますが、一致100する[10]*ものがないため、それは機能しません1。しかし、その後、エンジンは繰り返しの最後の文字を破棄し([10]*forのみを使用10)、再試行します。1が一致しないため、まだ機能しません0[10*]最初のキャラクターが完全にドロップされるまで、エンジンは一度に1つのキャラクターを捨てます。これで、残りの部分1と一致し、[10]*喜んで一致します。

このチュートリアルを読むことをお勧めします。これは、内部で何が起こっているかを非常によく説明しているためです。(特定の問題については、繰り返しのセクションを確認してください)。

詳細:

これは、繰り返しが貪欲であるか貪欲でないかには依存しません。正規表現エンジンは常にバックトラックします。[10]次のように貪欲にしないと、もう一方の端(0回の出現)から開始されます[10]*?。この場合、最初の試行はすでに一致しているため、プロセスが高速化されますが、常に一致するという事実は変わりません。

実際、繰り返しを「所有格」にすることで、エンジンがバックトラックするのを手動で防ぐことができます。これを行い、繰り返しが最初に残された場合、エンジンは他の可能な繰り返しを試行しません。これは構文になります:[10]*+。これで、エンジンは100その最初の部分とのみ一致します。その場合、マッチング1は失敗しますが、繰り返しを所有格にしたため、使用する別のオプションを試すために戻ることはありません[10]*。もちろん、この場合は役に立ちませんが、この動作が望ましいユースケースがあります。そして、これらすべてはリンクされたチュートリアルでもカバーされています。;)

于 2012-10-25T19:38:09.733 に答える
1

これはテストするのに十分簡単です。これが小さなphpスクリプトです:

<?php
if (preg_match('/[10]*1[10]*/', '100')) {
    echo "It matches.\n";
} else {
    echo "It doesn't match.\n";
}
?>

そして、出力は次のとおりです。

It matches.

説明:正規表現エンジンの試行とバックトラックを行った後、最終的な結果として、最初のエンジンは[10]*一致しません。は1テキスト1に一致し、2番目[10]*はテキストに一致します00

于 2012-10-25T19:39:57.303 に答える