Javascript Regex.prototype.exec在第二次迭代搜索时返回null 用例
我想在字符串中搜索几个匹配项。每个匹配最终都链接到对象数组中的对象特性。找到匹配项后,该匹配项将替换为对象中的另一个属性。问题是代码在第二次匹配时总是返回null 测试用例 这是我正在使用的测试用例。为了简化问题,我只是将所有匹配项替换为数字5,但请注意,最后的代码将用变量值替换匹配项 测试代码 下面是我用来测试和调试问题的代码。有趣的是,如果我更改Javascript Regex.prototype.exec在第二次迭代搜索时返回null 用例,javascript,regex,Javascript,Regex,我想在字符串中搜索几个匹配项。每个匹配最终都链接到对象数组中的对象特性。找到匹配项后,该匹配项将替换为对象中的另一个属性。问题是代码在第二次匹配时总是返回null 测试用例 这是我正在使用的测试用例。为了简化问题,我只是将所有匹配项替换为数字5,但请注意,最后的代码将用变量值替换匹配项 测试代码 下面是我用来测试和调试问题的代码。有趣的是,如果我更改var str='5+QUESTION_2',QUESTION_2将成功地替换为5。本质上,问题归结为第二个匹配始终返回null,即使它可以匹配 v
var str='5+QUESTION_2'
,QUESTION_2
将成功地替换为5。本质上,问题归结为第二个匹配始终返回null,即使它可以匹配
var re = /( |^)(QUESTION_1|QUESTION_2|QUESTION_3)( |$)/g;
var str = 'QUESTION_1 + QUESTION_2';
var rep = 5;
matches = re.exec(str);
var re2 = new RegExp("( |^)(" + matches[2] + ")( |$)", "g");
console.log(matches); // Returns a match on QUESTION_1
str = str.replace(re2, rep);
console.log(str); // Returns 5+ QUESTION_2
matches = re.exec(str);
console.log(matches); // Returns a match on NULL - doesn't find QUESTION_2
re2 = new RegExp("( |^)(" + matches[2] + ")( |$)", "g");
str = str.replace(re2, rep);
console.log(str); // Returns 5+ QUESTION_2
问题:
- 为什么第二个匹配项总是空的
- 可以在这里找到
re.lastIndex=0;
在下一次调用RegExp.exec之前
re.lastIndex=0
允许您重置搜索索引以从头开始执行第二次搜索。如果没有它,搜索将从最后一个匹配的索引开始,在本例中,这将产生null
阅读此文章了解更多信息。根据本手册:
仅当正则表达式使用“g”标志表示全局搜索时,才会设置此属性。在全局正则表达式上调用exec时,它会记住上次匹配的位置,并从那里开始下一次匹配
var rx = /a/g, matches = rx.exec('aa');
rx.lastIndex; //1
修改输入字符串时,在调用exec
之间,lastIndex
将被取消同步
虽然有几种方法可以解决这个问题,但我宁愿在一条语句中执行replace
'QUESTION1 + QUESTION2 + QUESTION3'.replace(/QUESTION\d+/g, function ($1) {
return 'VALUE_FOR_' + $1;
});
//"VALUE_FOR_QUESTION1 + VALUE_FOR_QUESTION2 + VALUE_FOR_QUESTION3"
选择的答案正确地识别了这个问题,但是我认为您应该按照我的建议去做,而不是依赖多个执行者和调整
lastIndex
。有趣的解决方案。我得好好玩玩这个。实际代码中的用例稍微复杂一些,但我认为这可以利用,并且可以简化我的生产问题。在生产问题中,替换也是可变的,我只是使用了QUESTION\uz?
来简化它。然而,对于这个特定的测试用例,这是一个更加优雅的解决方案+1。@先生,你的意思是,根据上一次的匹配,必须替换的内容可能会有所不同?如果你能解释你真正的问题,也许我能帮你找到一个有效的解决方案。我只是想让你知道你的解决方案是黄金。比原来的循环解决方案更优雅。非常感谢你的帮助。我希望我能接受这两个答案。@rampage先生,听到这个我很高兴。不幸的是,这是不可能的,你必须选择一个更好地回答这个问题。不仅是为了你,也为了其他人;)我只想说,将lastIndex
设置回0
可能会起作用,但不是在所有情况下都会起作用,因为它会在字符串的开头再次开始匹配。根据你的替代品,它可能会产生异常行为。