Javascript中的正则表达式没有它应有的贪婪吗?
我编写了一个简单的代码,用于捕获字符串中的某个组:Javascript中的正则表达式没有它应有的贪婪吗?,javascript,regex,Javascript,Regex,我编写了一个简单的代码,用于捕获字符串中的某个组: /[a-z]+([0-9]+)[a-z]+/gi (n chars , m digts , k chars). : 结果是: ["aaa111bbb", "111"] ["ccc333ddd", "333"] null 但是等一下, 为什么他不试试bbb222ccc部分 我是说, 它看到了aaa11bbb,但是他应该试试bbb222ccc。。。(太贪婪了!
/[a-z]+([0-9]+)[a-z]+/gi (n chars , m digts , k chars).
:
结果是:
["aaa111bbb", "111"]
["ccc333ddd", "333"]
null
但是等一下,
为什么他不试试bbb222ccc
部分
我是说,
它看到了aaa11bbb
,但是他应该试试bbb222ccc
。。。(太贪婪了!)
我错过了什么
阿尔索
看着
while (match != null)
{
match = myRegexp.exec(myString);
console.log(match)
}
它是如何发展到第二个结果的?
起初有:
var match=myRegexp.exec(myString)
稍后(在while循环中)
这是同一条线。。。它还记得第一个结果已经显示在哪里吗?
.exec
在使用g
标志时是有状态的。状态保存在regex对象的.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
或通过执行不同的字符串来重置状态<例如,code>re.exec(“”
将重置该状态,因为该状态是为'aaa11bbb222ccc33ddd'
保留的
同样的情况也适用于
.test
方法,因此,如果您不希望意外发生,请不要将g
标志与用于.test
的正则表达式一起使用。请参见您还可以手动更新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)
}
请参阅此链接
编辑:
顺便说一句,您的正则表达式应该是:
/[a-z]{3}([0-9]{3})[a-z]{3}/gi
,因为第一次匹配后的索引位于第一次匹配的末尾,bbb已经传递,除了字符串的其余部分(即“ccc333ddd”
)之外,没有任何内容需要匹配。贪婪意味着+
将尝试尽可能多地匹配,而不考虑正则表达式的下一部分可以匹配它。嗨@Esailija是的,我已经理解了。但是如果它像它说的那样贪婪,它就不是了。@Esailija请粘贴你的评论作为答案。@Esailija你能看看我的编辑吗?@RoyiNamir它是贪婪的-但它不会返回并重新检查它已经匹配的表达式的一部分。这是否意味着如果我没有将正则表达式保留在变量中,而且总是使用原始的/[a-z]+([0-9]+)[a-z]+/
,它就不会记得索引了?@RoyiNamir是的,当你创建一个新的regexp对象时,它还没有任何状态。换句话说,/[a-z]+([0-9]+)[a-z]+/gi.lastIndex==0
alwysI不理解测试部分。为什么我不应该对[g]使用test?因为它产生>1个结果?@RoyiNamir,因为它是使.exec
和.test
有状态工作的g
标志。如果删除g
标志,您会注意到与.exec
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);
}
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)
}