当我使用全局标志和大小写不敏感标志时,这个正则表达式有什么问题?查询是用户生成的输入。结果应该是[真,真]。
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”));
您正在使用一个RegExp对象并多次执行它。在每次连续执行时,它都从最后一个匹配索引开始。
你需要在每次执行前“重置”正则表达式,从头开始:
result.push(re.test('Foo Bar'));
re.lastIndex = 0;
result.push(re.test('Foo Bar'));
// result is now [true, true]
话虽如此,每次创建一个新的RegExp对象可能更具可读性(开销很小,因为RegExp是缓存的):
result.push((/Foo B/gi).test(stringA));
result.push((/Foo B/gi).test(stringB));
带有g标志的RegExp对象跟踪发生匹配的lastIndex,因此在后续匹配中,它将从最后使用的索引开始,而不是0。来看看:
var query = 'Foo B';
var re = new RegExp(查询,'gi');
console.log (re.lastIndex);
console.log(再保险。测试(Foo酒吧));
console.log (re.lastIndex);
console.log(再保险。测试(Foo酒吧));
console.log (re.lastIndex);
如果您不想在每次测试后手动将lastIndex重置为0,只需删除g标志。
下面是规范规定的算法(章节15.10.6.2):
RegExp.prototype.exec(字符串)
执行
字符串的正则表达式匹配
针对正则表达式和
返回一个数组对象
匹配的结果,或null
string did not match字符串
ToString(string)用于搜索
正则表达式的出现
模式如下:
Let R be this RexExp object.
Let S be the value of ToString(string).
Let length be the length of S.
Let lastIndex be the value of the lastIndex property on R.
Let i be the value of ToInteger(lastIndex).
If the global property is false, let i = 0.
If i < 0 or i > length then set the lastIndex property of R to 0 and return null.
Call [[Match]], giving it the arguments S and i. If [[Match]]
returned failure, go to step 9;
otherwise let r be its State result
and go to step 10.
Let i = i+1.
Go to step 7.
Let e be r's endIndex value.
If the global property is true, set the lastIndex property of R to e.
Let n be the length of r's captures array. (This is the same
value as 15.10.2.1's
NCapturingParens.)
Return a new array with the following properties:
The index
property is set to the position of the
matched substring within the complete
string S.
The input property is set
to S.
The length property is set to
n + 1.
The 0 property is set to the
matched substring (i.e. the portion of
S between offset i inclusive and
offset e exclusive).
For each
integer i such that i > 0 and i ≤ n,
set the property named ToString(i) to
the ith element of r's captures array.
函数是:
function parseDevName(name) {
var re = /^([^-]+)-([^-]+)-([^-]+)$/g;
var match = re.exec(name);
return match.slice(1,4);
}
var rv = parseDevName("BR-H-01");
rv = parseDevName("BR-H-01");
第一个电话起作用了。
第二个电话没有。切片操作抱怨一个空值。我认为这是因为re.lastIndex。这很奇怪,因为我希望每次调用函数时都分配一个新的RegExp,而不是在函数的多次调用之间共享。
当我把它改成:
var re = new RegExp('^([^-]+)-([^-]+)-([^-]+)$', 'g');
然后我就不会得到lastIndex延迟效应。正如我所期望的那样。
您正在使用一个RegExp对象并多次执行它。在每次连续执行时,它都从最后一个匹配索引开始。
你需要在每次执行前“重置”正则表达式,从头开始:
result.push(re.test('Foo Bar'));
re.lastIndex = 0;
result.push(re.test('Foo Bar'));
// result is now [true, true]
话虽如此,每次创建一个新的RegExp对象可能更具可读性(开销很小,因为RegExp是缓存的):
result.push((/Foo B/gi).test(stringA));
result.push((/Foo B/gi).test(stringB));