我正在使用java的Pattern.matches将一块数据与正则表达式进行匹配。数据块可以是单行或多行。问题是,一旦我的数据超过15行(通常超过17-18行),我就开始收到stackoverflowerror错误。对于少于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)?)+$";
我用来测试这个正则表达式的数据块是这样的
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
代码如下:
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
发布于 2011-10-05 22:18:29
我不能告诉您这个错误的原因;正则表达式本身是好的,不会受到灾难性的回溯或任何其他明显错误的影响。
也许你可以通过使用possessive quantifiers (++
代替+
,*+
代替*
,{2,}+
代替{2,}
等等)来减少正则表达式引擎保存的回溯位置的数量。此外,您不需要捕获组(感谢Thomas),所以我将它们更改为非捕获组:
"(?:(?:[a-zA-Z0-9][a-zA-Z0-9-]*+\\.)++([a-zA-Z]{2,}+)\\s*+,\\s*+\\d++\\s*+,\\s*+\\d++(\r?+\n)?+)++"
这不会改变正则表达式的行为(除了删除不必要的锚点,因为您使用的是Pattern.matches()
),但它可能有助于避免StackOverflows。我没有安装Java SDK,所以我不能自己测试它。
发布于 2011-10-05 22:23:10
我已经重现了这个问题,但只适用于更大的字符串。
$ java -version
java version "1.6.0_22"
OpenJDK Runtime Environment (IcedTea6 1.10.2) (6b22-1.10.2-0ubuntu1~11.04.1)
OpenJDK 64-Bit Server VM (build 20.0-b11, mixed mode)
我的测试代码:
public class Testje
{
public static void main(String... args)
{
String regex = "^(([a-zA-Z0-9][a-zA-Z0-9\\-]*\\.)+([a-zA-Z]{2,})\\s*,\\s*\\d+\\s*,\\s*\\d+(\\r?\\n)?)+$";
String data = "";
for (int i = 0; i<224; i++) data += "abc.com, 123, 456\n";
System.out.println(data.matches(regex));
}
}
对于该For循环中任何小于224的值,代码都可以正常运行。对于这一行的224个或更多副本,我得到了一个巨大的堆栈跟踪。
哦,请注意,使用(?:groups不会改变仍然有效的字符串的大小。
https://stackoverflow.com/questions/7662613
复制相似问题