Javascript中的正则表达式并不像它应该的那样贪婪



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

/[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);

稍后(在一段时间循环中)

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

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

当您

使用 g 标志时,.exec是有状态的。状态保存在正则表达式对象的 .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);
}

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

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

您也可以手动更新 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 执行官。


编辑:

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

最新更新