为什么这个正则表达式会杀死Java正则表达式引擎?

为什么这个正则表达式会杀死Java正则表达式引擎?,java,regex,Java,Regex,我有一个简单的正则表达式“正则表达式([\s]|[^Java正则表达式引擎崩溃的原因是正则表达式的这一部分导致堆栈溢出(事实上!): 然后,三个空格的字符串可以匹配为AAA、AAB、ABA、ABB、BAA、BAB、BBA或BBB。换句话说,正则表达式这部分的复杂性是2^N。这将杀死任何没有任何防护措施的正则表达式引擎 在正则表达式中使用替换(垂直条)时,始终确保替换是互斥的。也就是说,最多允许一个替换匹配任何给定的文本位。另一个问题(除了Jan所说的)就是在括号内一次匹配一个字符,相当于这个简化

我有一个简单的正则表达式“正则表达式
([\s]|[^Java正则表达式引擎崩溃的原因是正则表达式的这一部分导致堆栈溢出(事实上!):

然后,三个空格的字符串可以匹配为AAA、AAB、ABA、ABB、BAA、BAB、BBA或BBB。换句话说,正则表达式这部分的复杂性是2^N。这将杀死任何没有任何防护措施的正则表达式引擎

在正则表达式中使用替换(垂直条)时,始终确保替换是互斥的。也就是说,最多允许一个替换匹配任何给定的文本位。

另一个问题(除了Jan所说的)就是在括号内一次匹配一个字符,相当于这个简化示例:

(.)+
每次执行正则表达式的这一部分时,正则表达式引擎都必须保存由paren中的子表达式匹配的任何内容的开始和结束位置,以防需要回溯。即使它是非捕获组,也会如此,即

(?:.)+

…但由于它是一个捕获组,因此必须保存更多的信息。一次为一个字符检查所有这些信息会非常昂贵。将括号中的单个字符与组中的
*
+
量词相匹配几乎是不正确的。此外,您应该只使用捕获组当您需要捕获某些内容时,否则,请使用非捕获类型。

““
会更好。那么你就不需要最小匹配了。对无限循环的很好解释这个答案表明它实际上不是无限循环,只是一个指数时间的循环。我一周后回来发现了这个极好的答案。谢谢
[\s]|[^<]
A|B
(.)+
(?:.)+