Путаница в RegExp неохотный квантификатор? Джава - PullRequest
2 голосов
/ 14 мая 2010

Почему я получаю вывод ab для следующего кода регулярного выражения с квантификатором Relucutant?

    Pattern p = Pattern.compile("abc*?");
    Matcher m = p.matcher("abcfoo");
    while(m.find())
      System.out.println(m.group()); // ab

Точно так же, почему я получаю пустые индексы для следующего кода?

   Pattern p = Pattern.compile(".*?");
   Matcher m = p.matcher("abcfoo");
   while(m.find())
     System.out.println(m.group());

Ответы [ 5 ]

7 голосов
/ 14 мая 2010

В дополнение к ответу Конрада Рудольфа:

abc*?

соответствует "ab" в любом случае и "c" только в том случае, если должно . Поскольку ничто не следует за *?, двигатель регулярного выражения останавливается немедленно. Если у вас было:

abc*?f

тогда он будет соответствовать "abcf", потому что "c" должен совпадать, чтобы позволить "f" также совпадать. Другое выражение:

.*?

ничего не соответствует, потому что этот шаблон на 100% необязательный.

.*?f

будет соответствовать "abcf" снова.

5 голосов
/ 14 мая 2010

*? соответствует нулю или более совпадений, но соответствует как можно меньшему количеству (и, кстати, это обычно называют «не жадным», а не «неохотным»). Поэтому, если возможно нулевое совпадение, это оптимальное совпадение.

Чего именно вы хотите достичь? Возможно, не жадное сопоставление - это не то, что вам нужно.

2 голосов
/ 14 мая 2010

Квантификатор ? не позволяет .* соответствовать как можно меньшему количеству символов, но только большему количеству символов, если это требуется для возврата.

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

Группа захвата \1 в первом шаблоне является жадной: она сначала сопоставляется со всем и занимает столько же времени, сколько и при возврате. Таким образом, шаблон найдет максимально возможное совпадение префикса / суффикса:

    System.out.println(
        "abracadabra".replaceAll("^(.+).*\\1$", "($1)")
    ); // prints "(abra)"

Теперь \1 во втором паттерне неохотно; сначала он ничего не соответствует, и требует больше, поскольку он возвращается. Таким образом, шаблон найдет самое короткое совпадение префикса / суффикса:

    System.out.println(
        "abracadabra".replaceAll("^(.+?).*\\1$", "($1)")
    ); // prints "(a)"

В вашем случае .*? может соответствовать пустой строке, и вам больше не нужно возвращать ее назад и сопоставлять больше, поскольку этого было достаточно для сопоставления всего шаблона.

Смотри также


Вот еще один иллюстративный пример неохотного квантификатора при конечном повторении:

Здесь x{3,5} является жадным и займет как можно больше.

    System.out.println(
        "xxxxxxx".replaceAll("x{3,5}", "Y")
    ); // prints "Yxx"

Здесь x{3,5}? неохотно и займет как можно меньше.

    System.out.println(
        "xxxxxxx".replaceAll("x{3,5}?", "Y")
    ); // prints "YYx"
2 голосов
/ 14 мая 2010

Никогда не имеет смысла иметь неохотный квантификатор как последнее в регулярном выражении. Неохотный квантификатор соответствует только тому количеству, которое необходимо для достижения общего соответствия. Это означает, что должно быть что-то после квантификатора, чтобы оно продолжало совпадать.

Если кажется странным иметь что-то, что может быть использовано таким бессмысленным использованием, возможно, это связано с тем, что неохотные квантификаторы являются надстройкой, а это невозможно с «настоящими» регулярными выражениями. Некоторые другие примеры бессмысленного использования - это «квантификатор» {1} и \b+ или любое другое утверждение нулевой ширины (^, $, обходные пути и т. Д.) С квантификатором. Некоторые разновидности рассматривают последнее как синтаксическую ошибку; Java это позволяет, но, конечно, применяет утверждение только один раз.

0 голосов
/ 22 мая 2013
     *?-> also call it as Lasy star
        ^abc*?f
    *?----> repeats  0 or more times
    ^---> regular expression for start of the string
      Example:  abcf00abcf00 --->Matches:"abcf"00abcf00
In this case c must select to reach f

        abc*? 
    *?----> repeats 0 or more times 
    Matches ab
      Example:  abcabcabcabc -----> Matches:"ab"c"ab"c"ab"c"ab"c

        abc.* matches any character except line break
       Example: abcabababbababab --->Matches:"abcabababbababab"

        ab.*?
      example:  ababababbababab ---> "ab""ab""ab""ab""ab""ab""ab""ab"
    abc? matsches ab or abc
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...