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

时间:2012-11-30 14:41:57

标签: javascript regex

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

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

code

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

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

2 个答案:

答案 0 :(得分: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);
}

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

同样适用于.test方法,因此如果您不希望出现意外,请不要将g标记用于.test使用的正则表达式。见https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp/exec

答案 1 :(得分: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