регулярное выражение собственническое квантификатор против ленивых или жадных - PullRequest
1 голос
/ 15 июля 2010

Может кто-нибудь объяснить мне, шаг за шагом, почему регулярное выражение не с этим:

<.++>

с этой строкой для сравнения: <em>

Эта же строка найдена с ленивымили жадные квантификаторы, но в этом случае какие шаги предпринимаются?

Я использую Java Regex flavour.

Ответы [ 3 ]

12 голосов
/ 15 июля 2010

Из документации Java Pattern :

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

В вашем примере < в вашем регулярном выражении соответствует < в строке, затем .++ соответствует всей оставшейся части строки, em>.У вас все еще есть > в вашем регулярном выражении, но в строке не осталось символов для соответствия (потому что .++ поглотил их всех).Таким образом, совпадение не удается.

Если бы квантификатор был жадным, то есть если бы он был .+ вместо .++, в этот момент механизм регулярных выражений попытался бы уменьшить часть, сопоставленную на .+, на один символ, чтобы просто em, и попробуйте снова.На этот раз совпадение будет успешным, потому что в строке останется > для совпадения > в регулярном выражении.

РЕДАКТИРОВАТЬ: Ленивый квантификатор будет работать какжадный квантификатор наоборот.Вместо того, чтобы начинать с попытки сопоставить всю оставшуюся часть строки и отступать символ за символом, ленивый квантификатор начинал бы с попытки сопоставить один символ, в данном случае просто e.Если это не позволяет полному регулярному выражению совпадать (чего не было бы здесь, потому что у вас было бы > в регулярном выражении, пытающемся сопоставить m в строке), ленивый квантификатор переместился бы до совпадения двухсимволы, em.Тогда > в регулярном выражении будет совпадать с > в строке, и совпадение будет успешным.Однако, если это не сработает, ленивый квантификатор будет перемещаться до трех символов и т. Д.

4 голосов
/ 15 июля 2010

Квантификатор-обладатель предотвращает возврат назад - таким образом, часть .++ соответствует оставшейся строке em>, что также поглощает последнюю >.

Следовательно, последнее > регулярного выражения не соответствует и регулярное выражение не выполняется.

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

3 голосов
/ 15 июля 2010

На жадном варианте

Сначала давайте рассмотрим, как шаблон, подобный <.+>, сопоставляется с <em>:

  • < в шаблоне соответствует < в
  • Затем .+ соответствует em> на входе (поскольку он жадный, сначала он будет соответствовать как можно большему числу .)
    • Тогда > не делаетt совпадают, поскольку во входных данных больше нет символов
  • В этот момент .+ возвращается и должно соответствовать на один меньше .;поэтому .+ теперь соответствует em
  • Теперь > в шаблоне соответствует > на входе.

На неохотном варианте

В отличие от этого, <.+?> совпадает с <em>:

  • < в шаблоне соответствует < на входе.
  • Тогда .+? соответствует e на входе (поскольку оно неохотно, но должно занимать хотя бы один .)
    • Тогда > не совпадает, поскольку остальная часть ввода равна m>
  • В этот момент .+ возвращается и должен соответствовать еще одному .;теперь .+? соответствует em
  • Теперь > в шаблоне соответствует > во входных данных.

В классе отрицательных символов и квантификаторах притяженийcombo

Обратите внимание, что в любом из вышеперечисленных случаев .+ или .+? должны быть возвращены для соответствия >.Вот почему <.++> может НИКОГДА соответствовать <em>, потому что вот что происходит:

  • < в шаблоне соответствует < на входе
  • Тогда .++ соответствует столько же . на входе, и будет обладать этим совпадением
    • Он не отпустит то, что ему соответствует!(следовательно, «притяжательный»)
    • В этом случае .++ может соответствовать em>
  • Теперь > в шаблоне никогда не может совпадать, потому чтолюбой > будет сожран .++
    • Так как это притяжательное, .++ не будет "сотрудничать", возвращая >

Образец, который, по крайней мере, имеет шанс на совпадение, - <[^>]++>.При сопоставлении с <em>:

  • < в шаблоне совпадает с < на входе
  • Тогда [^>]++ собственно совпадает с [^>] ввход (т. е. все, кроме >)
    • В этом случае он будет собственнически соответствовать em
  • Теперь > в шаблоне может соответствовать >во входных данных

Насколько это возможно, вам следует воздерживаться от использования .*? / .* в вашем паттерне.. слишком гибок, поскольку он соответствует (почти!) Любому символу, и это может привести к ненужному обратному отслеживанию и / или совпадению.

Когда это применимо, вы должны использовать отрицательный класс символов вместо .

регулярные выражения.инфо

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

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