RegEx花费了太多时间和记忆

时间:2018-06-13 12:04:37

标签: java regex string

我有这个RegEx模式

    ^(\\d|\\w)+\\..*

这是我的输入

    (1) nu11111111111111
    (2) nu1111111111111111111
    (3) nu1111111111111111111111111111111111111

输入2的时间高于输入1并返回未匹配结果。但是对于输入3,即使执行30分钟后我也没有得到任何响应。我也在观察记忆,并且不断增加。

以下是我的代码段:

    String input1 = "nu11111111111111";
    String input2 = "nu1111111111111111111";
    String input3 = "nu1111111111111111111111111111111111111";
    try
    {

        if (input3.matches("^(\\d|\\w)+\\..*"))
        {
            System.out.println("Matched");
        }
        else
        {
            System.out.println("Not Matched");
        }
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }

2 个答案:

答案 0 :(得分:3)

这是灾难性回溯的另一个案例,因为\d已经包含\w。由于找不到匹配项,正则表达式引擎会尝试回溯到与您的\w系列匹配的\d1的所有可能组合 - 这是相当多的。

要了解正在发生的事情,请参阅https://regex101.com/r/4fRRpc/1/并转到正则表达式调试器。这使用了一个没有启动优化的PCRE模式,这应该与java在这种情况下的表现非常相似。

对于正则表达式,请改用^\\w+\\..*

答案 1 :(得分:0)

Java正则表达式引擎很可悲。

› time perl -E'say /^(\d|\w)+\..*/ ? "Matched" : "Not Matched" for qw(nu11111111111111 nu1111111111111111111 nu1111111111111111111111111111111111111)'
Not Matched
Not Matched
Not Matched

real    0m0,009s
user    0m0,006s
sys     0m0,003s

尝试RE2,它不会回溯并具有Java绑定。