Почему нет?работать в качестве необязательного спецификатора повторения в этом шаблоне? - PullRequest
2 голосов
/ 22 июля 2010

Я пытаюсь сопоставить входные данные, такие как

<foo>
<bar>
#####<foo>
#####<bar>

Я пытался #{5}?<\w+>, но он не соответствует <foo> и <bar>.

Что не так с этим шаблоном и как его можно исправить?

Ответы [ 2 ]

11 голосов
/ 22 июля 2010

Вкл. ? для необязательного или нежелательного

Метасимвол ? в Java regex (и некоторых других разновидностях) может иметь два совершенно разных значения, в зависимости от того, где он появляется.Сразу после спецификатора повторения ? является неохотным квантификатором, а не «ноль или один» / «необязательный» спецификатор повторения.

Таким образом, #{5}? не означает «необязательно совпадение 5 #».Это на самом деле говорит "матч 5 # неохотно".Возможно, не имеет смысла пытаться сопоставить «ровно 5, но как можно меньше», но на самом деле это означает, что этот шаблон означает.


Группировка на помощь!

Один из способов решения этой проблемы - сгруппировать необязательный шаблон как (…)?.Примерно так должно работать для этой проблемы:

(#{5})?<\w+>

Теперь ? не сразу следует за спецификатором повторения (то есть *, +, ? или {…});он следует за закрывающей скобкой, используемой для группировки.

В качестве альтернативы, вы также можете использовать группу без захвата (?:…) в этом случае:

(?:#{5})?<\w+>

Это обеспечивает тот же эффект группировки, ноне включается в \1.

Ссылки

Смежные вопросы


Бонусный материал: как насчет ??

Стоит отметить, что вы можете использовать ??, чтобы неохотно сопоставлять дополнительный элемент!

    System.out.println("NOMZ".matches("NOMZ??"));
    // "true"

    System.out.println(
          "NOM NOMZ NOMZZ".replaceAll("NOMZ??", "YUM")
    ); // "YUM YUMZ YUMZZ"

Обратите внимание, что Z?? является необязательным Z, но это неохотно."NOMZ" в целом все еще matches шаблон NOMZ??, но в replaceAll, NOMZ?? может соответствовать только "NOM" и не должен принимать дополнительный Z, даже если он там есть.

В отличие от этого, NOMZ? будет жадно соответствовать опциональному Z: если он есть, он его примет.

    System.out.println(
          "NOM NOMZ NOMZZ".replaceAll("NOMZ?", "YUM")
    ); // "YUM YUM YUMZ"

Смежные вопросы

2 голосов
/ 22 июля 2010

Поместите # совпадение в подшаблон:

(#{5})?<\w+>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...