0

.この正規表現の が文字列全体と貪欲に一致しない理由がわかりません。

var re = /.+b/g,
    st = "aaaaaabcd";

console.log( st.match(re) ); //["aaaaaab"]

http://jsbin.com/UmOraTI/1/edit?js,出力

私は貪欲について学ぼうとしてきましたが、基本的にすべてに一致するため、すべての文字に.+一致する必要があるようです. と同じです。誰かがこれを説明できますか?.*

4

4 に答える 4

2

まあ、.+確かに貪欲です...あなたはそれを見ないだけです!

正規表現エンジンはd、文字列内の までのすべての文字に一致し、そこに到達すると を探しますがb、どこにも見つかりません。

したがって、1文字戻って(バックトラッキングと呼ばれます)、 と の間cにあり、dと 再び一致しようとしbますが、成功しません(dは前にあり、 ではありませんb)。

bとの間に入るために再びバックトラックしますが、c再び失敗します。

もう一度バックトラックして間aに入ってb、ついにマッチ!そこでバックトラックを停止し、表示される結果を返します。

これがあなたが得る理由です:

var re = /.+b/g,
    st = "aaaaaabcdbaa";

console.log( st.match(re) ); //["aaaaaabcdb"]

a最後の 2秒後にバックトラックし、最後の b.

これは貪欲です!

逆に……

var re = /.+?b/g,
    st = "aaaaaabcdbaa";

console.log( st.match(re) ); //["aaaaaab"]

これは怠惰です。

一部のエンジンには、このバックトラッキングを防止する演算子があり、このプロセスにより正規表現が非常に遅くなることがよくあります。単一の文字列 (.*通常は多くの文字列) で何度もバックトラックする必要があると想像してください。

于 2013-09-13T18:43:36.473 に答える
0

実際には、ある意味で、文字列全体に一致します。正規表現マッチャーはbacktrackingと呼ばれるものを実行します。これにより、適切な一致が見つかるまでバックアップが行われます。だからあなたの表現で:

/.+b/

試合は次のようになります。

    aaaaaabcd
.+  ---------
b            x

次に、be に一致しないことが判明したため、.+用語はその一致の 1 つを「放棄」し、mather は再試行します。

    aaaaaabcd
.+  --------
b           x

まだ一致しないので、次の状態になるまで別の (これは役に立たない) と別のをあきらめます。

    aaaaaabcd
.+  ------
b         -

これは、正規表現の最長一致です。

于 2013-09-13T18:43:15.907 に答える
0
var re = /<tr>.*<\/tr>/g,
    st = "<tr>asdf</tr>blah<tr>asdf</tr>";

console.log( st.match(re) );

正規表現での貪欲な数学には注意する必要があります。上記の例でも、文字列全体に一致します。jsbin から取得します。

于 2013-09-13T18:44:18.727 に答える