为什么带有全局标志的RegExp会产生错误的结果? [英] Why does a RegExp with global flag give wrong results?

查看:183
本文介绍了为什么带有全局标志的RegExp会产生错误的结果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我使用全局标志和不区分大小写的标志时,这个正则表达式有什么问题?查询是用户生成的输入。结果应为[true,true]。

What is the problem with this regular expression when I use the global flag and the case insensitive flag? Query is a user generated input. The result should be [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"));

推荐答案

RegExp 对象跟踪 lastIndex 匹配发生,因此在后续匹配时,它将从最后使用的索引开始,而不是0。看看:

The RegExp object keeps track of the lastIndex where a match occurred, so on subsequent matches it will start from the last used index, instead of 0. Take a look:

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'));

如果您不想手动重置 lastIndex 为0,只需删除 g 标志。

If you don't want to manually reset lastIndex to 0 after every test, just remove the g flag.

这是规格所要求的算法(第15.10.6.2节:

Here's the algorithm that the specs dictate (section 15.10.6.2):


RegExp.prototype.exec(字符串)

对正则表达式执行字符串

a正则表达式匹配,
返回包含匹配的
结果的Array对象,如果是
string不匹配字符串
ToString(string)搜索正则表达式
模式的
出现次数如下:

Performs a regular expression match of string against the regular expression and returns an Array object containing the results of the match, or null if the string did not match The string ToString(string) is searched for an occurrence of the regular expression pattern as follows:


  1. 设S为ToString(字符串)的值。

  2. 设长度为S的长度。

  3. 让lastIndex成为lastIndex属性的值。

  4. 让我成为ToInteger(lastIndex)的值。

  5. 如果全球财产是fals e,让i = 0。

  6. 如果我< 0或I> length然后将lastIndex设置为0并返回null。

  7. 调用[[Match]],为其赋予参数S和i。如果[[Match]]
    返回失败,请转到步骤8;
    否则让r为其州结果
    并转到步骤10.

  8. 让i = i + 1。

  9. 转到步骤6.

  10. 设e是r的endIndex值。

  11. 如果global属性为true,则将lastIndex设置为e。 / strong>

  12. 设n为r的捕获数组的长度。 (这与15.10.2.1的
    NCapturingParens的
    值相同。)

  13. 返回具有以下属性的新数组:


    • 索引
      属性设置为完整
      字符串S中
      匹配子字符串的位置。

    • 输入属性设置为
      到S.

    • 长度属性设置为
      n + 1.

    • 0属性设置为
      匹配的子字符串(即
      S在offset i包含和
      offset e exclusive之间的部分)。

    • 每个
      整数i使I> 0且I≤n,
      将名为ToString(i)的属性设置为
      r的捕获数组的第i个元素。

  1. Let S be the value of ToString(string).
  2. Let length be the length of S.
  3. Let lastIndex be the value of the lastIndex property.
  4. Let i be the value of ToInteger(lastIndex).
  5. If the global property is false, let i = 0.
  6. If I < 0 or I > length then set lastIndex to 0 and return null.
  7. Call [[Match]], giving it the arguments S and i. If [[Match]] returned failure, go to step 8; otherwise let r be its State result and go to step 10.
  8. Let i = i+1.
  9. Go to step 6.
  10. Let e be r's endIndex value.
  11. If the global property is true, set lastIndex to e.
  12. Let n be the length of r's captures array. (This is the same value as 15.10.2.1's NCapturingParens.)
  13. 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.


这篇关于为什么带有全局标志的RegExp会产生错误的结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆