同じ正規表現マッチングを数回実行すると、奇妙な動作が見られます。
var r = /(.*)/g
var d = "a"
console.log(r.exec(d))
console.log(r.exec(d))
これにより、次が生成されます。
["a", "a"]
["", ""]
2回目で何も一致しないのはなぜですか?
同じ正規表現マッチングを数回実行すると、奇妙な動作が見られます。
var r = /(.*)/g
var d = "a"
console.log(r.exec(d))
console.log(r.exec(d))
これにより、次が生成されます。
["a", "a"]
["", ""]
2回目で何も一致しないのはなぜですか?
それが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 = ["", ""]
明らかにループが終了しないため)。しかし、いずれにせよ、あなたのパターンは*
. 何にでも一致できます (無を含む)。少なくとも使用します.+
。どんな目的でも。
exec
最初の一致を返し、内部ポインターを前方に移動します。このようにして、2 番目の呼び出しは 2 番目の一致を返します。
一致するものは 1 つしかないため、2 番目の呼び出しでは空の結果が返されます。