Pattern.matches()给出了StackOverflowError

Pur*_*hah 18 java regex stack-overflow

我正在使用java的Pattern.matches将数据块与正则表达式进行匹配.数据块可以是单行或多行.问题是,一旦我的数据超过15行(通常超过17-18行),我开始得到stackoverflower.对于少于15行的数据,正则表达式工作正常.

正则表达式的格式为:
domainname - > space - >, - > space - > number - > space - >, - > space - > number - > newline

String regex = "^(([a-zA-Z0-9][a-zA-Z0-9\\-]*\\.)+([a-zA-Z]{2,})\\s*,\\s*\\d+\\s*,\\s*\\d+(\\r?\\n)?)+$";
Run Code Online (Sandbox Code Playgroud)

我用来测试这个正则表达式的数据块就是这个

abc.com, 123, 456
abc.com, 123, 456
abc.com, 123, 456
abc.com, 123, 456
abc.com, 123, 456
abc.com, 123, 456
abc.com, 123, 456
abc.com, 123, 456
abc.com, 123, 456
abc.com, 123, 456
abc.com, 123, 456
abc.com, 123, 456
abc.com, 123, 456
abc.com, 123, 456
abc.com, 123, 456
abc.com, 123, 456
abc.com, 123, 456
abc.com, 123, 456
Run Code Online (Sandbox Code Playgroud)

这是代码:

String regex = "^(([a-zA-Z0-9][a-zA-Z0-9\\-]*\\.)+([a-zA-Z]{2,})\\s*,\\s*\\d+\\s*,\\s*\\d+(\\r?\\n)?)+$";
boolean valid = Pattern.matches(regex, data); //fails here
Run Code Online (Sandbox Code Playgroud)

Tim*_*ker 9

我无法告诉你这个错误的原因; 正则表达式本身很好,不会受到灾难性的回溯或任何其他明显的错误.

也许你可以减少回溯位置的正则表达式引擎节省使用数量占有欲量词(++而不是+,*+不是*,{2,}+不是{2,}等).此外,您不需要捕获组(感谢Thomas),所以我将它们更改为非捕获组:

"(?:(?:[a-zA-Z0-9][a-zA-Z0-9-]*+\\.)++([a-zA-Z]{2,}+)\\s*+,\\s*+\\d++\\s*+,\\s*+\\d++(\r?+\n)?+)++"
Run Code Online (Sandbox Code Playgroud)

这不会改变正则表达式的行为(除了你正在使用时删除不必要的锚点Pattern.matches()),但它可能有助于避免StackOverflows.我没有安装Java SDK,所以我不能自己测试它.

  • 如果你将最终的`+`(正则表达式的末尾)改为`++`,有什么改变吗? (2认同)