对于具有全局选项的模式,连续调用RegExp测试失败
Consecutive calls to RegExp test fail for pattern with global option
我一整天都在纠结这个问题,我不知道我是否做错了什么,或者我是否在Chrome的JavaScript引擎中发现了一个bug。似乎连续调用具有全局标志的RegExp
对象会对相同的输入字符串返回不一致的结果。我正在测试以下函数:
function testRegex(pattern, array) {
document.writeln('Pattern = ' + pattern + ', Array = ' + array + '<br/>');
for (var ii = 0; ii < array.length; ii++) {
document.writeln(ii + ', ');
document.writeln(array[ii] + ', ');
document.writeln(pattern.test(array[ii]) + '<br />');
}
document.writeln('<br/>');
}
当我用/a/g
作为模式和各种字符串数组调用函数时,我得到以下结果,据我所知,其中许多是不正确的:
// EXPECTED: True
// ACTUAL: True
testRegex(/a/g, ['a']);
// EXPECTED: True, True
// ACTUAL: True, False
testRegex(/a/g, ['a', 'a']);
// EXPECTED: True, True, True
// ACTUAL: True, False, True
testRegex(/a/g, ['a', 'a', 'a']);
// EXPECTED: True, False, True
// ACTUAL: True, False, True
testRegex(/a/g, ['a', 'b', 'a']);
// EXPECTED: True, True, True, True
// ACTUAL: True, False, True, False
testRegex(/a/g, ['a', 'a', 'a', 'a']);
// EXPECTED: True, False, False, True
// ACTUAL: True, False, False, True
testRegex(/a/g, ['a', 'b', 'b', 'a']);
当我用相同的字符串数组调用相同的函数,但传递/a/
作为模式时,实际结果都与预期结果匹配。
// EXPECTED: True
// ACTUAL: True
testRegex(/a/, ['a']);
// EXPECTED: True, True
// ACTUAL: True, True
testRegex(/a/, ['a', 'a']);
// EXPECTED: True, True, True
// ACTUAL: True, True, True
testRegex(/a/, ['a', 'a', 'a']);
// EXPECTED: True, False, True
// ACTUAL: True, False, True
testRegex(/a/, ['a', 'b', 'a']);
// EXPECTED: True, True, True, True
// ACTUAL: True, True, True, True
testRegex(/a/, ['a', 'a', 'a', 'a']);
// EXPECTED: True, False, False, True
// ACTUAL: True, False, False, True
testRegex(/a/, ['a', 'b', 'b', 'a']);
我已经创建了上面代码的工作示例:http://jsfiddle.net/FishBasketGordo/gBWsN/
我错过了什么吗?结果不应该是相同的给定数组的字符串无论是否模式是全局的吗?注意,我主要是在Chrome上工作,但我在Firefox 4和IE 8中也观察到类似的错误结果。
如果您按照如下方式更改测试循环:
for (var ii = 0; ii < array.length; ii++) {
document.writeln(ii + ', ');
document.writeln(array[ii] + ', ');
document.writeln(pattern.test(array[ii]) + '<br />');
pattern.lastIndex = 0;
}
那么你的代码就可以工作了。问题是"g"标志导致RegExp对象卡住。由于"g",在该循环的第一次迭代之后,"lastIndex"的值被设置为1。如果你没有设置它来重置搜索,那么它会假设在第二次调用时你要求它继续从偏移量1开始。
在".replace()"调用上下文之外的正则表达式上使用"g"标志会产生奇怪的语义含义。
这不是一个bug,而是一个特性。你得到的结果不是"不正确",只是出乎意料。
10.3.2。RegExp实例属性
每个RegExp对象有五个属性。source属性是一个只读字符串,其中包含正则表达式的文本。全局属性是一个只读布尔值,用于指定正则表达式是否具有g标志。ignoreCase属性是一个只读布尔值,用于指定正则表达式是否具有i标志。multiline属性是一个只读布尔值,用于指定正则表达式是否具有m标志。最后一个属性是lastIndex,一个读写整数。对于带有g标志的模式,该属性存储字符串中下一次搜索开始的位置。exec()和test()方法使用它,如前一节所述。
源- setTimeout()在其设置时间之前连续调用回调函数
- 为什么你不能通过连续调用 .text() JQuery 来逃避
- 连续的 ajax 调用会冻结 chrome 和 IE
- 每次提交时,Ajax 表单开始和成功处理程序的调用次数会连续增加
- Javascript For Loop - 播放列表中的连续 Ajax 调用
- 连续调用 javascript 函数,直到条件
- 连续调用多个函数
- 显示快速连续 AJAX 调用的结果
- 在jQuery UI中,如何防止连续调用时运行数百万次的“脉动”效应
- 处理快速连续的函数调用 - Javascript / underscore.js / node.js
- 在连续的AJAX调用上使用async
- javascript函数调用返回未定义和页面连续加载
- 如何在按下按钮并打洞时连续调用函数
- 一个HTML按钮可连续调用3个函数
- 与连续的setTimeout调用相比,setInterval更有可能按时发生
- 替代"async: false"用于连续的AJAX调用
- 我有连续的ajax调用,我如何用返回的数据构造一个表
- AngularJS连续的$http调用没有返回正确的数据
- 如何通过连续的AJAX调用来维护PHP对象
- 将连续调用的函数中的值保存到数组中