为什么正则表达式获得stackOverFlow

时间:2016-10-13 17:49:42

标签: java regex scala

当我尝试使用scala lib(使用re2)匹配上面的正则表达式时,代码进入下面的路径并超出1分钟:

正则表达式:

(([a-z0-9!#$%&'*+?^_`{|}~-]+(?:.[a-z0-9!#$%&'*+=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])))

堆栈追踪:

at java.util.regex.Pattern$CharProperty.match(Pattern.java:3693)
at java.util.regex.Pattern$Curly.match(Pattern.java:4125)
at java.util.regex.Pattern$CharProperty.match(Pattern.java:3694)
at java.util.regex.Pattern$GroupHead.match(Pattern.java:4556)
at java.util.regex.Pattern$Loop.match(Pattern.java:4683)
at java.util.regex.Pattern$GroupTail.match(Pattern.java:4615)
at java.util.regex.Pattern$Curly.match0(Pattern.java:4170)
at java.util.regex.Pattern$Curly.match(Pattern.java:4132)
at java.util.regex.Pattern$CharProperty.match(Pattern.java:3694)

我不确定它的无限循环是否可能在很长一段时间后起作用。 我需要帮助理解这个表达式究竟是什么导致了这种情况发生以及如何改进这个表达式。

2 个答案:

答案 0 :(得分:2)

您的正则表达式具有嵌套量词(例如(a+)*)。这是works well with re2not with most other regular expression engines

答案 1 :(得分:1)

字符类外的正则表达式中的未转义点与任何字符匹配,但与换行符号匹配。这意味着在您的模式中,有两个未转义的点可以与相邻的子模式匹配相同的模式:(?:.?.)+

如果您在regex101.com上加载模式并针对ggggg@gggggggggggggggggggg进行测试,您将看到(使用PCRE设置)引擎需要数千个步骤才能完成匹配。

这是因为未转义的点位于量化组内。

这也是ggggg@cccc也与您的模式匹配的原因。

由于你很可能意味着匹配文字点,所以逃避它们:

(([a-z0-9!#$%&'*+?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])))

请参阅regex demo

请注意,您可能希望在整个模式周围删除2个捕获组,因为您似乎不需要它们。