我创建一个RegExp对象(在JavaScript中)来测试是否存在数字:
var test = new RegExp( '[0-9]', 'g' );
我像这样使用它
console.log( test.test( '0' ) ); // true
console.log( test.test( '1' ) ); // false - why?
这个输出更令人困惑:
console.log( test.test( '1' ) ); // true
console.log( test.test( '0' ) ); // false - why?
console.log( test.test( '1' ) ); // true
console.log( test.test( '2' ) ); // false - why?
console.log( test.test( '2' ) ); // true - correct, but why is this one true?
如果我删除了g
限定符,则其行为符合预期。
这是我认为的错误,还是规范的一些特殊部分? g
限定符是否应该以这种方式使用? (我正在为多个任务重复使用相同的表达式,因此完全具有限定符)
答案 0 :(得分:7)
每个文档:https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp/test#Description
在同一个全局正则表达式实例上多次调用的
test
将超过上一个匹配。
您可以确认此行为:
var test = new RegExp( '[0-9]', 'g' );
test.test('01'); //true
test.test('01'); //true
test.test('01'); //false
如果您想要的是确认针对各种字符串的单个匹配,则使用g
标记是没有意义的。
答案 1 :(得分:6)
删除'g'
标志。当您使用'g
'标志时,它会更新正则表达式的lastIndex
属性(准备对相同的字符串进行连续搜索),然后从该索引值开始下一次搜索(从而为您提供在下次搜索时误读。)
答案 2 :(得分:1)
根据MDN,
与
exec
(或与其结合使用)一样,test
多次调用 在同一个全局正则表达式实例上将超越 上一场比赛。
从技术上讲,ECMAScript 5.1规范说
15.10.6.3 RegExp.prototype.test(字符串)
采取以下步骤:
- 让match为使用 string 作为此RegExp对象评估
RegExp.prototype.exec
(15.10.6.2)算法的结果 参数。- 如果匹配不为null,则返回
醇>true
;否则返回false
。15.10.6.2 RegExp.prototype.exec(字符串)
对常规执行 string 的正则表达式匹配 表达式并返回一个包含结果的Array对象 匹配,或
null
如果字符串不匹配。搜索字符串ToString( string )是否存在 正则表达式如下:
- 让 R 成为此RegExp对象。
- [...]
- [...]
- 让 lastIndex 成为使用参数"
lastIndex
"调用 R 的[[Get]]内部方法的结果。- 让 i 为ToInteger( lastIndex )的值。
- 让 global 成为使用参数"
global
"调用 R 的[[Get]]内部方法的结果。- 如果全球为
false
,则让 i = 0.- [...]
- [...]
- 让 e 成为 r 的 endIndex 值。
- 如果全球为
true
,
- 使用参数"
lastIndex
", e 和{{1}调用 R 的[[Put]]内部方法}}。- [...]
醇>
因此,为避免此行为,您可以
避免使用全局标记true
这样,在第7步,g
将i
而不是0
。
每次使用后手动重置lastIndex
lastIndex
属性的值指定String位置 哪个开始下一场比赛。
例如,
lastIndex
使用var test = /[0-9]/g;
test.test('0'); // true
test.lastIndex; // 1
test.lastIndex = 0;
test.test('1'); // true
或match
字符串方法
search
将match
重置为0,lastIndex
忽略它:
15.5.4.10 String.prototype.match(regexp)
[...] [If] global 为
search
,使用参数"调用 rx 的[[Put]]内部方法。true
"和0. [...]15.5.4.12 String.prototype.search(regexp)
[...]从值的开头搜索值 string 正则表达式模式 rx 。 [...]
lastIndex
和lastIndex
执行搜索时,将忽略 regexp 的属性。 [...]
例如,
global