Java 为什么正则表达式会出现堆栈溢出
当我尝试使用scala lib(使用re2)匹配上述正则表达式时,代码进入以下路径并超时1分钟: 正则表达式:Java 为什么正则表达式会出现堆栈溢出,java,regex,scala,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(P
(([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)
我不确定它的无限循环是否会在长时间持续后工作。
我需要帮助理解此表达式中到底是什么导致了这种情况,以及如何改进此表达式。您的正则表达式具有嵌套的量词(例如
(a+)*
)。但是。您的正则表达式有嵌套的量词(例如,(a+)*
)。字符类之外的正则表达式中的此but.未替换点与除换行符以外的任何字符匹配。这意味着在模式中,有两个未缩放的点可以与相邻子模式匹配相同的模式:(?:.
和?)+
如果您在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])))
见
请注意,您可能希望删除整个模式中的两个捕获组,因为您似乎不需要它们。字符类之外的正则表达式中的未缩放点与除换行符以外的任何字符匹配。这意味着在模式中,有两个未缩放的点可以与相邻子模式匹配相同的模式:
(?:.
和?)+
如果您在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])))
见
请注意,您可能希望删除整个模式中的两个捕获组,因为您似乎不需要它们。添加有关输入的更多详细信息,您试图用这个正则表达式实现的目标似乎不是无限的,您是否正在尝试验证电子邮件或其他内容?如果增加堆栈大小会发生什么情况?点不是转义的-
(?:,,?)+
,必须转义以匹配文字点。这可能会在您的案例中引起问题。这是为了验证电子邮件地址吗?电子邮件地址比name@domain.com; 不建议使用正则表达式验证它们。请添加有关输入的更多详细信息,您试图使用此regex plus实现的目标似乎不是无限的,您是否正在尝试验证电子邮件或其他内容?如果增加堆栈大小会发生什么情况?点不会转义-(?:.
,)+
,它必须转义以匹配文字点。这可能会在您的案例中引起问题。这是为了验证电子邮件地址吗?电子邮件地址比name@domain.com; 不建议使用正则表达式验证它们。FYI,(?:[a-z0-9-]*[a-z0-9])
结尾处可以写成[a-z0-9-]*[a-z0-9]
FYI,(?:[a-z0-9-]*[a-z0-9])
结尾处可以写成[a-z0-9-]*[a-z0-9]