首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Pattern.matches()提供StackOverflowError

Pattern.matches()提供StackOverflowError
EN

Stack Overflow用户
提问于 2011-10-05 22:08:33
回答 2查看 1.9K关注 0票数 18

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

正则表达式的格式如下:

domainname -> space ->,-> space -> number -> space ->,-> space -> number -> newline

代码语言:javascript
复制
String regex = "^(([a-zA-Z0-9][a-zA-Z0-9\\-]*\\.)+([a-zA-Z]{2,})\\s*,\\s*\\d+\\s*,\\s*\\d+(\\r?\\n)?)+$";

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

代码语言:javascript
复制
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

代码如下:

代码语言:javascript
复制
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
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-10-05 22:18:29

我不能告诉您这个错误的原因;正则表达式本身是好的,不会受到灾难性的回溯或任何其他明显错误的影响。

也许你可以通过使用possessive quantifiers (++代替+*+代替*{2,}+代替{2,}等等)来减少正则表达式引擎保存的回溯位置的数量。此外,您不需要捕获组(感谢Thomas),所以我将它们更改为非捕获组:

代码语言:javascript
复制
"(?:(?:[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,所以我不能自己测试它。

票数 9
EN

Stack Overflow用户

发布于 2011-10-05 22:23:10

我已经重现了这个问题,但只适用于更大的字符串。

代码语言:javascript
复制
$ 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)

我的测试代码:

代码语言:javascript
复制
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不会改变仍然有效的字符串的大小。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7662613

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档