3

RegExps の exec メソッドを使用して、文字列内のすべての一致を検索できることはよく知られています。ただし、正規表現が空の文字列と一致すると、このループが永久にスタックする可能性があることがわかりました

var s = '1234'
var r = /()/g;
var m;
var i = 0;
while( (m = r.exec(s)) ){
   console.log(i, m[0]);
   if(++i >= 50){ console.log("infinite loop!"); break }
}

しかし、本当に奇妙なのは、プレーンな string.match メソッドがスタックしないことです:

'1234'.match(/()/g) // Gives ["", "", "", "", "", ""]

exec ループとは異なる動作をするように match メソッドがどのように定義されているのだろうか。これまでのところ、match メソッドのように行き詰まるのを避ける唯一の方法は、恐ろしいハックで string.replace メソッドを悪用することです。

var matches = [];
'1234'.replace(/()/g, function(m){ matches.push(m) });

だから私の質問は:

正規表現が空の文字列と一致する場合、一致と置換はどのように有限の結果を返しますか? 同じ手法を使用して、exec ループでスタックしないようにすることはできますか?

4

1 に答える 1

3

1 つの (厄介な) 解決策は、前回と同じ場所にないことを確認することです。

var s = '1234'
var r = /()/g;
var m;
var i = 0;
var lastPosition = -1;

while(m = r.exec(s)) {
    if(m.index === lastPosition) {
        r.lastIndex++;
        continue;
    }

    lastPosition = m.index;

    console.log(i, m[0]);
}
于 2012-07-07T02:18:07.463 に答える