abo*_*out 254 javascript regex
当我使用全局标志和不区分大小写的标志时,这个正则表达式有什么问题?查询是用户生成的输入.结果应该是[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]
Run Code Online (Sandbox Code Playgroud)
var reg = /^a$/g;
for(i = 0; i++ < 10;)
console.log(reg.test("a"));Run Code Online (Sandbox Code Playgroud)
Ion*_*tan 326
该RegExp对象跟踪lastIndex匹配发生的位置,因此在后续匹配时它将从最后使用的索引开始,而不是0.看看:
var query = 'Foo B';
var re = new RegExp(query, 'gi');
var result = [];
result.push(re.test('Foo Bar'));
alert(re.lastIndex);
result.push(re.test('Foo Bar'));Run Code Online (Sandbox Code Playgroud)
如果您不想lastIndex在每次测试后手动重置为0,只需删除该g标志即可.
这是规范规定的算法(第15.10.6.2节):
RegExp.prototype.exec(串)
对正则表达式执行字符串的正则表达式匹配,并返回包含匹配结果的Array对象;如果字符串不匹配,则返回null.搜索字符串ToString(string)以查找正则表达式模式的出现,如下所示:
- 设S为ToString(string)的值.
- 设长度为S的长度.
- 设lastIndex为lastIndex属性的值.
- 让我成为ToInteger(lastIndex)的值.
- 如果全局属性为false,则让i = 0.
- 如果I <0或I> length,则将lastIndex设置为0并返回null.
- 调用[[Match]],给它参数S和i.如果[[Match]]返回失败,请执行步骤8; 否则让r成为其状态结果并转到步骤10.
- 设i = i + 1.
- 转到第6步.
- 设e是r的endIndex值.
- 如果global属性为true,则将lastIndex设置为e.
- 设n是r的捕获数组的长度.(这与15.10.2.1的NCapturingParens值相同.)
- 返回具有以下属性的新数组:
- index属性设置为完整字符串S中匹配的子字符串的位置.
- input属性设置为S.
- length属性设置为n + 1.
- 0属性设置为匹配的子字符串(即,在offset i包含和offset e exclusive之间的S部分).
- 对于每个整数i,使得I> 0且I≤n,将名为ToString(i)的属性设置为r的captures数组的第i个元素.
Roa*_*rth 68
您正在使用单个RegExp对象并多次执行它.在每次连续执行时,它从最后一个匹配索引继续.
您需要"重置"正则表达式,以便在每次执行之前从头开始:
result.push(re.test('Foo Bar'));
re.lastIndex = 0;
result.push(re.test('Foo Bar'));
// result is now [true, true]
Run Code Online (Sandbox Code Playgroud)
已经说过每次创建一个新的RegExp对象可能更具可读性(无论如何,由于RegExp被缓存,开销很小):
result.push((/Foo B/gi).test(stringA));
result.push((/Foo B/gi).test(stringB));
Run Code Online (Sandbox Code Playgroud)
Jam*_*mes 34
RegExp.prototype.test更新正则表达式的lastIndex属性,以便每个测试将从最后一个测试停止的位置开始.我建议使用,String.prototype.match因为它不更新lastIndex属性:
!!'Foo Bar'.match(re); // -> true
!!'Foo Bar'.match(re); // -> true
Run Code Online (Sandbox Code Playgroud)
注意:!!将其转换为布尔值,然后反转布尔值,以便反映结果.
或者,您可以重置该lastIndex属性:
result.push(re.test('Foo Bar'));
re.lastIndex = 0;
result.push(re.test('Foo Bar'));
Run Code Online (Sandbox Code Playgroud)
小智 10
删除全局g标志将解决您的问题.
var re = new RegExp(query, 'gi');
Run Code Online (Sandbox Code Playgroud)
应该
var re = new RegExp(query, 'i');
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
42087 次 |
| 最近记录: |