5

我制作了一个简单的代码来捕获字符串中的某个组:

/[a-z]+([0-9]+)[a-z]+/gi    (n chars , m digts , k chars).

代码

var myString='aaa111bbb222ccc333ddd';
var myRegexp=/[a-z]+([0-9]+)[a-z]+/gi;

var match=myRegexp.exec(myString);
console.log(match)
 
 while (match != null)
{
  match = myRegexp.exec(myString);
  console.log(match)
}

结果是:

["aaa111bbb", "111"]
["ccc333ddd", "333"]
null

但是等一下,为什么他没有尝试这个bbb222ccc部分?

我的意思是,它看到了,aaa111bbb但他应该尝试一下bbb222ccc……(太贪心了!)

我错过了什么?

看着

   while (match != null)
    {
      match = myRegexp.exec(myString);
      console.log(match)
    }

它是如何发展到第二个结果的?起初有:

var match=myRegexp.exec(myString);

稍后(在一个while循环中)

match=myRegexp.exec(myString);
match=myRegexp.exec(myString);

它是同一行......它在哪里记得第一个结果已经显示?

4

2 回答 2

4

.exec使用g标志时是有状态的。状态保存在正则表达式对象的.lastIndex属性中。

var myString = 'aaa111bbb222ccc333ddd';
var myRegexp = /[a-z]+([0-9]+)[a-z]+/gi;
var match = myRegexp.exec(myString);
console.log(myRegexp.lastIndex); //9, so the next `.exec` will only look after index 9
while (match != null) {
    match = myRegexp.exec(myString);
    console.log(myRegexp.lastIndex);
}

可以通过设置.lastIndex0或通过execing不同的字符串来重置状态。re.exec("")例如将重置状态,因为状态被保留为'aaa111bbb222ccc333ddd'.

这同样适用于.test方法,因此,如果您不喜欢意外,切勿将g标志与正则表达式一起使用。.test请参阅https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp/exec

于 2012-11-30T14:52:19.690 回答
2

您还可以手动更新lastIndex属性:

var myString='aaa111bbb222ccc333ddd';
var myRegexp=/[a-z]+([0-9]+)[a-z]+/gi;

var match=myRegexp.exec(myString);
console.log(match);

 while (match != null)
{
  myRegexp.lastIndex -= match[0].length - 1; // Set the cursor to the position just after the beginning of the previous match
  match = myRegexp.exec(myString);
  console.log(match)
}

请参阅此链接MDN exec


编辑 :

顺便说一句,您的正则表达式应该是:/[a-z]{3}([0-9]{3})[a-z]{3}/gi

于 2012-11-30T14:54:45.713 回答