当我使用全局标志和不区分大小写的标志时,这个正则表达式有什么问题?查询是用户生成的输入 . 结果应该是[true,true] .
var query = 'Foo B';
var re = new RegExp(query, 'gi');
var result = [];
result.push(re.test('Foo Bar'));
result.push(re.test('Foo Bar'));
// result will be [true, false]
var reg = /^a$/g;
for(i = 0; i++ < 10;)
console.log(reg.test("a"));
6 回答
RegExp
对象跟踪发生匹配的lastIndex,因此在后续匹配时,它将从上次使用的索引开始,而不是0.看看:如果您不想在每次测试后手动将
lastIndex
重置为0,只需删除g
标志即可 .这是规范规定的算法(第15.10.6.2节):
您正在使用单个
RegExp
对象并多次执行它 . 在每次连续执行时,它从最后一个匹配索引继续 .您需要“重置”正则表达式,以便在每次执行之前从头开始:
说过每次创建一个新的RegExp对象可能更具可读性(无论如何,由于RegExp被缓存,开销很小):
RegExp.prototype.test 更新正则表达式' lastIndex 属性,以便每个测试将从最后一个测试停止的位置开始 . 我建议使用 String.prototype.match ,因为它不会更新 lastIndex 属性:
注意: !! 将其转换为布尔值,然后反转布尔值,以便反映结果 .
或者,您可以重置 lastIndex 属性:
删除全局
g
标志将解决您的问题 .应该
使用/ g标志告诉它在命中后继续搜索 .
If the match succeeds, the exec() method returns an array and updates properties of the regular expression object.
在您第一次搜索之前:
第一次搜索后
删除g并在每次调用exec()后退出搜索 .
我有这个功能:
第一个电话有效 . 第二个电话没有 .
slice
操作抱怨空值 . 我认为这是因为re.lastIndex
. 这很奇怪,因为我希望每次调用函数时都会分配一个新的RegExp
,而不是在我的函数的多次调用中共享 .当我把它改成:
然后我没有得到
lastIndex
保持效果 . 它可以像我期望的那样工作 .