零长度正则表达式和无限匹配?

时间:2015-12-28 14:50:36

标签: regex

在试图详细解答this问题的答案时,我现在试图接受零长度正则表达式的行为/含义。

我经常使用www.regexr.com作为游乐场来测试/调试/了解正则表达式中的内容。

所以我们有这个最平庸的场景:

正则表达式为a*

输入字符串为dgwawa (事实上​​,这里的字符串是无关紧要的)

为什么报告此正则表达式将无限匹配的行为,因为它匹配前一个字符的零次出现?

为什么结果是6个匹配,每个字符位置一个(因为在每个字符中,无论是否是a,都有匹配,因为零匹配是匹配的)?< / p>

如何进入无限匹配?那么它一次检查/进展一个字符?

我想知道它是如何/在何处进入无限循环。

enter image description here

2 个答案:

答案 0 :(得分:17)

regexr.com在线正则表达式测试程序专为JavaScript正则表达式测试而设计。当可以匹配空字符串的模式传递时,JavaScript正则表达式引擎不会自动移动索引。

这就是为什么当您需要模拟在.NET Regex.Matches,PHP preg_match_all,Python re.finditer等中观察到的行为时,您需要手动推进索引以测试每个位置

请参阅regex101.com test

var re = /a*/g; 
var str = 'dgwawa';
var m;
 
while ((m = re.exec(str)) !== null) {
    if (m.index === re.lastIndex) {   // <- this part
        re.lastIndex++;               // <- here
    }                                 // <- is important
    document.body.innerHTML += "'" + m[0] + "'<br/>";
}

如果删除if块,则会出现无限循环。

在这方面有两件非常重要的事情需要提及:

  • 始终使用适合您的编程语言的在线正则表达式测试程序
  • 避免使用可以匹配空字符串的非锚定模式

答案 1 :(得分:1)

实际上有7场比赛

让我枚举它们,第一个数字是开始(0基础),第二个数字是长度

Match 1:             0       0   
Match 2:             1       0   
Match 3:             2       0   
Match 4:    a        3       1   
Match 5:             4       0   
Match 6:    a        5       1   
Match 7:             6       0   

我使用regex101,它完成了我们大多数人对这个简单的正则表达式的期望(假设有正则表达式)。

https://regex101.com/r/mN4jA4/1