4

次の正規表現コードがあるとします。

var str = "{$ for ( var i = 0, len = O.length; i < len; i++ ) { $}";

var reg = /\{\$(.*?)\$\}/g;

console.log(reg.test(str));

console.log(reg.test(str));

console.log(reg.test(str));

結果が True と False の交互になるのはなぜですか?

4

3 に答える 3

3

ドキュメントごと:

文字列にパターンが含まれているかどうかを知りたい場合は、test メソッドを使用します (String.search メソッドと同様)。詳細については (ただし、実行速度は遅くなります)、exec メソッドを使用します (String.match メソッドに似ています)。exec (またはそれと組み合わせて) と同様に、同じグローバル正規表現インスタンスに対して複数回呼び出されたテストは、前の一致を超えて進みます。

何が起こっているかを説明するために、何が起こっているのかを使用execして見ることができます。パスの順序:

  1. 元の文字列(true)文字
    列全体が一致し、true と評価されます。
  2. null(偽)
    連続した呼び出しが続くため、最初の呼び出しで結果全体が返されたため、 が残りnullます。
  3. 元の文字列(真実)
    そしてパターンは最初に戻って続きます。

証明のために、次を実行します

var str = '{$ for ( var i = 0, len = O.length; i < len; i++ ) { $}';
var reg = /\{\$(.*?)\$\}/g;
for (var i = 0; i < 3; i++){
    var result = reg.exec(str);
    console.log(result);
    console.log(!!result);
}
于 2013-03-27T03:04:52.147 に答える
2

JavaScriptは、最後に一致したインデックスなどのフィールドを含め、状態を内部的にRegExp維持します。そのため、例のように正規表現を再利用すると、興味深い動作が見られます。

この/gフラグによりtrue​​、指定された文字列 (この例ではたまたま 1 つしかありません) に対する連続する一致ごとに 1回返さfalseれ、その後、1 回返されてから最初からやり直されます。各呼び出しの間に、前述のlastIndexプロパティが適宜更新されます。

次の点を考慮してください。

var str = "12";
var regex = /\d/g;

console.log(regex.test(str)); // true
console.log(regex.test(str)); // true
console.log(regex.test(str)); // false

対:

console.log(/\d/g.test(str)); // true
console.log(/\d/g.test(str)); // true
console.log(/\d/g.test(str)); // true
console.log(/\d/g.test(str)); // true
// ...and so on, since you're instantiating a new RegExp each time
于 2013-03-27T03:05:01.297 に答える
0

面白い発見!グローバル修飾子 '/g' と関係があると思います。グローバル修飾子を削除すると、期待どおりに機能するようです。私は正規表現の専門家ではありません。.test() は、2 回一致するべきではありませんが、$ シンボルを反復処理できると推測することしかできませんでした。

于 2013-03-27T03:04:10.983 に答える