Выражение регулярного выражения в простом английском - PullRequest
5 голосов
/ 11 мая 2010

Я работаю над новым проектом Java и, следовательно, я читаю уже существующий код. В очень важной части кода, если найдено следующее выражение регулярного выражения, и я не могу точно сказать, что они делают. Кто-нибудь может объяснить простым языком, что они делают ??

1)

 [^,]*|.+(,).+

2)

(\()?\d+(?(1)\))

Ответы [ 3 ]

17 голосов
/ 11 мая 2010

В следующий раз, когда вам понадобится объяснение регулярных выражений, вы можете воспользоваться следующей услугой explain.pl от Рика Мишама:

Regex: [^,]*|.+(,).+

NODE                     EXPLANATION
--------------------------------------------------------------------------------
  [^,]*                    any character except: ',' (0 or more times
                           (matching the most amount possible))
--------------------------------------------------------------------------------
 |                        OR
--------------------------------------------------------------------------------
  .+                       any character except \n (1 or more times
                           (matching the most amount possible))
--------------------------------------------------------------------------------
  (                        group and capture to \1:
--------------------------------------------------------------------------------
    ,                        ','
--------------------------------------------------------------------------------
  )                        end of \1
--------------------------------------------------------------------------------
  .+                       any character except \n (1 or more times
                           (matching the most amount possible))

Regex: (\()?\d+(?(1)\))

NODE                     EXPLANATION
--------------------------------------------------------------------------------
  (                        group and capture to \1 (optional
                           (matching the most amount possible)):
--------------------------------------------------------------------------------
    \(                       '('
--------------------------------------------------------------------------------
  )?                       end of \1 (NOTE: because you're using a
                           quantifier on this capture, only the LAST
                           repetition of the captured pattern will be
                           stored in \1)
--------------------------------------------------------------------------------
  \d+                      digits (0-9) (1 or more times (matching
                           the most amount possible))
--------------------------------------------------------------------------------
  (?(1)                    if back-reference \1 matched, then:
--------------------------------------------------------------------------------
    \)                       ')'
--------------------------------------------------------------------------------
   |                        else:
--------------------------------------------------------------------------------
                             succeed
--------------------------------------------------------------------------------
  )                        end of conditional on \1

Ссылки


Примечание к условным обозначениям

JAVA НЕ ПОДДЕРЖИВАЕТ УСЛОВИЙ! Безусловное регулярное выражение для второго шаблона будет выглядеть примерно так:

\d+|\(\d+\)

т.е.. ненулевое повторение цифр с круглыми скобками или без них.

Ссылки


Узоры в глубине

Вот тестовый жгут для первого паттерна

    import java.util.regex.*;
    //...

    Pattern p = Pattern.compile("[^,]*|.+(,).+");
    String[] tests = {
        "",       // [] is a match with no commas
        "abc",    // [abc] is a match with no commas
        ",abc",   // [,abc] is not a match
        "abc,",   // [abc,] is not a match
        "ab,c",   // [ab,c] is a match with separating comma
        "ab,c,",  // [ab,c,] is a match with separating comma
        ",",      // [,] is not a match
        ",,",     // [,,] is not a match
        ",,,",    // [,,,] is a match with separating comma
    };
    for (String test : tests) {
        Matcher m = p.matcher(test);
        System.out.format("[%s] is %s %n", test,
            !m.matches() ? "not a match"
            : m.group(1) != null
               ? "a match with separating comma"
               : "a match with no commas"
        );
    }

Заключение

  • Для соответствия строка должна попадать в один из следующих двух случаев:
    • Не содержит запятую (возможно, пустую строку)
    • Содержит запятую, разделяющую две непустые строки
  • На совпадении \1 может использоваться для различения двух случаев

А вот аналогичный тестовый комплект для второго шаблона, переписанный без использования условий (который не поддерживается Java):

    Pattern p = Pattern.compile("\\d+|(\\()\\d+\\)");
    String[] tests = {
        "",       // [] is not a match
        "0",      // [0] is a match without parenthesis
        "(0)",    // [(0)] is a match with surrounding parenthesis
        "007",    // [007] is a match without parenthesis
        "(007)",  // [(007)] is a match with surrounding parenthesis
        "(007",   // [(007] is not a match
        "007)",   // [007)] is not a match
        "-1",     // [-1] is not a match
    };
    for (String test : tests) {
        Matcher m = p.matcher(test);
        System.out.format("[%s] is %s %n", test,
            !m.matches() ? "not a match"
            : m.group(1) != null
               ? "a match with surrounding parenthesis"
               : "a match without parenthesis"
        );
    }

Как уже говорилось ранее, это соответствует ненулевому числу цифр, возможно, заключенных в круглые скобки (а \1 различает два).

9 голосов
/ 11 мая 2010

1)

[^,]* means any number of characters that are not a comma
.+(,).+ means 1 or more characters followed by a comma followed by 1 or more characters
|  means either the first one or the second one

2)

(\()? means zero or one '('  note* backslash is to escape '('
\d+ means 1 or more digits
(?(1)\)) means if back-reference \1 matched, then ')' note* no else is given

Также обратите внимание, что круглые скобки используются для захвата определенных частей регулярного выражения, за исключением, конечно, если они экранированы обратной косой чертой

0 голосов
/ 11 мая 2010

1) Все, что не начинается с запятой, или все, что содержит запятую между ними.

2) Любое число, которое заканчивается на 1 и находится в скобках, возможно, закрыто до и открытоснова после номера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...