Java regex очень медленный (переводит вложенные квантификаторы в собственнические квантификаторы) - PullRequest
1 голос
/ 16 июля 2011

Я обнаружил, что это регулярное выражение соответствует URL (первоначально в Javascript от Daring Fireball), которое в 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 работает очень медленно , что проблема в этом блоке кода:

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

, и кажется, что для решения проблемы мне нужно сделать эти внутренние квантификаторы притяжательными (что на самом делевложены), но я не знаю, как это сделать. Спасибо за советы и извините за мой плохой английский!

Ответы [ 2 ]

3 голосов
/ 16 июля 2011

Вы можете избежать всего этого, используя java.net.URL или java.net.URI для анализа URL.


  1. java.io.URI лучше разбирает работу, чем java.net.URL. Попробуйте это.

  2. После того, как вы проанализировали URL, вы можете проверить каждый из компонентов; например проверьте, что имя хоста может быть разрешено.

  3. Если вы хотите, чтобы URL-адреса разрешались, вам нужно различать абсолютные и неабсолютные URL-адреса и проверять, является ли «схема» той, с которой вы можете справиться.

  4. Вы не можете проверить, работает ли URL (т. Е. Соответствует ли он извлекаемому ресурсу), фактически не пытаясь открыть ресурс. И даже это не является окончательным тестом по ряду возможных причин.

0 голосов
/ 16 июля 2011

Возможно, вы столкнулись с катастрофическим возвратом: убедитесь, что ваше регулярное выражение не совпадает с одними и теми же символами в нескольких группах, что приводит к увеличению количества комбинаций, которые необходимо проверить.

См. эту статью для объяснения.

...