2

同じ正規表現マッチングを数回実行すると、奇妙な動作が見られます。

var r = /(.*)/g
var d = "a"

console.log(r.exec(d))
console.log(r.exec(d))

これにより、次が生成されます。

["a", "a"]
["", ""]

2回目で何も一致しないのはなぜですか?

4

2 に答える 2

7

それがgフラグの役割です。これを使用すると、exec は前の一致の終わりから次の検索を続行します。しかし、最初の一致 ( a) の後、文字列には何も残っていないため、空の一致が得られます。この空の一致は、通常、execループを終了するために使用されます。一致するものが 1 つしかないことがわかっている場合は、を削除しますg(「グローバル」検索を意味します)。

これらの括弧を取り除くことができる (そして取り除くべき) ことに注意してください。パフォーマンスが犠牲になるだけです。aそれらがないと、結果の配列に1つしか取得できません。

複数の一致を考慮したいが、最後の空の一致を無視する場合は、ループ テクニックを使用します。

var match;
while(match = r.exec(d))
    // process match[0] here

実際に (意味のある) キャプチャ グループがある場合にのみ、このループが必要であることに注意してください。そうでない場合(完全な一致のみを取得したい場合)、match代わりに elclanrs が指摘するように使用できます:

var matches = d.match(r);

編集:

私が言ったことのほとんどは部分的に真実ですが、実際の原因ではないことに気付きました["", ""]. 実際に起こることはこれです: 最初の.*マッチa. 前回の一致の後 ( の後a)、エンジンが 2 回目の検索の継続を試みます。パターンには.*(0 個以上の文字を意味する) があるため、空の文字列に引き続き一致します (パターンに一致するため)。また、空の文字列に一致しても、次の検索の位置は進みません。したがって、(はそのような場合に中止するのに十分賢い).matchを取得します。["a", ""]match

実際、その正規表現をループ手法で使用すると、無限ループが発生します (match = ["", ""]明らかにループが終了しないため)。しかし、いずれにせよ、あなたのパターンは*. 何にでも一致できます (無を含む)。少なくとも使用します.+。どんな目的でも。

于 2012-12-13T21:39:00.523 に答える
1

exec最初の一致を返し、内部ポインターを前方に移動します。このようにして、2 番目の呼び出しは 2 番目の一致を返します。

一致するものは 1 つしかないため、2 番目の呼び出しでは空の結果が返されます。

于 2012-12-13T21:39:20.117 に答える