在this article上,它提到了
确保您清楚表达模式的事实 测试每个角色。而那,只是因为引擎 在遵循模式并寻找匹配时向前移动 仍然回溯并检查字符串中的每个字符,直到匹配为止 找到或者设置全局标志直到所有字符都是 检查。
但我在Javascript中测试了
"aaa@bbb".match(/a+@b+/g)
不会产生如下结果:
["aaa@bbb", "aa@bbb", "a@bbb"]
它只生成["aaa@bbb"]
。它似乎没有检查每个字符来测试模式。任何人都可以解释一下匹配步骤吗?谢谢。
答案 0 :(得分:4)
/g
并不意味着它会尝试在输入字符串中找到可能与给定模式匹配的每个可能的字符子集。这意味着一旦找到匹配,它将继续搜索可能与从上一个匹配开始的模式匹配的更多子串。
例如:
"aaa@bbb ... aaaa@bbbb".match(/a+@b+/g);
将产生
["aaa@bbb", "aaaa@bbbb"]
答案 1 :(得分:4)
这个解释混合了两个不同的概念,即IMO应该分开
在寻找匹配时,量词(?
,*
,+
)的正常行为是“贪婪”,即尽可能地咀嚼......例如,在使用/(a+)([^b]+)/
测试的aaaacccc
中,所有a
都将成为第1组的一部分,即使它们当然也匹配字符集[^b]
(除{{1}之外的所有内容})。
然而,如果过多抓取会阻止匹配,则RE规则要求量词“回溯”捕获较少,如果这允许表达式匹配。例如,在使用b
测试的(a+)([^b]+)
中,组1将只获得三个aaaa
s,为组2留下一个匹配。
您可以使用“非贪婪量词”更改此贪婪行为,例如a
,*?
,+?
。在这种情况下,引擎仍然会回溯,但具有相反的含义:非贪婪的子表达式会尽可能少地使用来允许表达式的其余部分匹配。例如,使用??
测试的(a+)(a+b+)
将为组1留下两个aaabbb
,为组2留下a
,但是abbb
具有相同的字符串将只留下第1组为(a+?)(a+b+)
,因为这是允许匹配剩余部分的最小值。
请注意,由于回溯,如果表达式匹配与否,贪婪/非贪婪选项不会改变,但只有匹配的大小和每个子表达的大小。
这与回溯完全无关,只是意味着搜索必须找到所有非重叠匹配,而不是在第一场比赛停止。这是通过找到第一个匹配,然后在匹配结束后再次开始搜索来完成的。
请注意,每个匹配都是使用标准正则表达式规则计算的,并且不同匹配之间没有前瞻或后退:换句话说,如果使得例如较短的贪婪匹配会在字符串中提供更多匹配,则不考虑此选项使用a
测试的a+[^b]+
即使指定了aaaaaa
选项也只会提供一个匹配,即使子字符串g
,aa
,{ {1}}每个都是正则表达式的有效匹配。
答案 2 :(得分:0)
当使用全局标志时,它会在上一场比赛结束后开始搜索下一场比赛,以防止产生大量重叠的比赛。
答案 3 :(得分:0)
如果您未指定/g
,则只要找到匹配项,引擎就会停止。
如果您指定/g
,它将在匹配后继续运行。但是,它仍然不会产生重叠的匹配,这就是你所要求的。
答案 4 :(得分:0)
因为。,
正则表达式尝试做什么:
所有正则表达式都将尝试匹配best match.
正则表达式不会做什么
它与您的情况下的单个匹配组合不匹配。
"aaa@bbb".match(/a+@b+/g)
方案有效
相反,aaa@bbbHiaa@bbbHelloa@bbbSEEYOU
尝试这样的事情,它会给你
aaa@bbb
aa@bbb
a@bbb