Нежадное регулярное выражение не выбирает ближайший выбор - PullRequest
4 голосов
/ 05 февраля 2012

Мое регулярное выражение не выбирает ближайшую пару 'cont' для внутреннего текста. Как я могу это исправить?

Введите:

cont cont ItextI /cont /cont

Regex:

cont.*?I(.*?)I.*?/cont

Match:

cont cont ItextI /cont

Матч мне нужно:

cont ItextI /cont

Ответы [ 2 ]

12 голосов
/ 05 февраля 2012
cont(?:(?!/?cont).)*I(.*?)I(?:(?!/?cont).)*/cont

будет соответствовать только внутреннему блоку.

Пояснение:

cont        # match "cont"
(?:         # Match...
 (?!/?cont) # (as long as we're not at the start of "cont" or "/cont")
 .          # any character.
)*          # Repeat any number of times.
I           # Match "I"
(.*?)       # Match as few characters as possible, capturing them.
I           # Match "I"
(?:         # Same as above
 (?!/?cont)
 .
)*
/cont       # Match "/cont"

Это явно запрещает cont или /cont появляться между открывающим cont и текстом для захвата (и между этим текстом и заключительным /cont).

2 голосов
/ 05 февраля 2012

Причина, по которой вы подходите на cont cont ItextI /cont, заключается в том, что регулярное выражение соответствует первой части вашего шаблона cont на первом "cont", а затем использует неохотный .*?, чтобы поглотить пробел, следующий cont и пробелпредшествующий ItextI.Когда он достигает ItextI, он распознает I как соответствующий следующей части шаблона и продолжает с остальным регулярным выражением.Как пишет Minitech, это потому, что регулярное выражение работает с начала строки и находит самое раннее возможное совпадение.

Если вы можете делать предположения относительно пробела, вы можете написать:

cont\s+I(.*?)I\s+/cont

Это будет соответствовать в вашем примере выше.

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