Java正则表达式非常慢(将嵌套量词转换为占有量词)

时间:2011-07-16 08:48:38

标签: java regex url pattern-matching quantifiers

我发现这个正则表达式匹配url(最初是由Daring Fireball在Javascript中),这在java中有效但在某些情况下极其缓慢:

private final static String pattern = 
"\\b" + 
"(" +                            // Capture 1: entire matched URL
  "(?:" +
    "[a-z][\\w-]+:" +                // URL protocol and colon
    "(?:" +
      "/{1,3}" +                        // 1-3 slashes
      "|" +                             //   or
      "[a-z0-9%]" +                     // Single letter or digit or '%'
                                        // (Trying not to match e.g. "URI::Escape")
    ")" +
    "|" +                            //   or
    "www\\d{0,3}[.]" +               // "www.", "www1.", "www2." … "www999."
    "|" +                            //   or
    "[a-z0-9.\\-]+[.][a-z]{2,4}/" +  // looks like domain name followed by a slash
  ")" +
  "(?:" +                           // One or more:
    "[^\\s()<>]+" +                      // Run of non-space, non-()<>
    "|" +                               //   or
    "\\((?:[^\\s()<>]+|(?:\\([^\\s()<>]+\\)))*\\)" +  // balanced parens, up to 2 levels
  ")+" +
  "(?:" +                           // End with:
    "\\((?:[^\\s()<>]+|(?:\\([^\\s()<>]+\\)))*\\)" +  // balanced parens, up to 2 levels
    "|" +                                   //   or
    "[^\\s`!\\-()\\[\\]{};:'\".,<>?«»“”‘’]" +        // not a space or one of these punct chars (updated to add a 'dash'
  ")" +
")";

我发现主题:Java Regular Expression running very slow问题出现在这段代码中:

"(?:" +                           // One or more:
"[^\\s()<>]+" +                      // Run of non-space, non-()<>
"|" +                               //   or
"\\((?:[^\\s()<>]+|(?:\\([^\\s()<>]+\\)))*\\)" +  // balanced parens, up to 2 levels
")+"

似乎要解决问题我需要使这些内部量词占有欲(实际上是嵌套的),但我不知道如何做到这一点 感谢您的建议并抱歉我的BAD英语!

2 个答案:

答案 0 :(得分:3)

您可以使用java.net.URLjava.net.URI来解析网址,从而避免所有这些。


  1. java.io.URIjava.net.URL更好地解析。试试那个。

  2. 解析网址后,您可以检查每个组件;例如检查主机名是否可以解析。

  3. 如果您想要解决的网址,您需要区分绝对网址和非绝对网址,并检查“方案”是否可以应对。

  4. 无法检查网址是否正常工作(即它对应于可检索资源),而不实际尝试打开资源。由于许多可能的原因,即使这不是明确的测试。

答案 1 :(得分:0)

您可能遇到灾难性回溯的情况:检查您的正则表达式是否与多个组中的相同字符不匹配,从而导致必须检查的失控数量的组合。

请参阅this article以获取解释。