Регулярное выражение ленивый перед захватом группы

Используя следующее регулярное выражение

<w:p.*?\$\{test\}.*?\/w:p>

Я пытаюсь соответствовать первому

<w:p>

перед "${test}" и первым

</w:p>

после. После работал просто отлично, используя? квантификатор, но он отказывается останавливаться на первом

<w:body><w:p w:rsidRDefault="00271ADB"/><w:p w:rsidR="00C15291"><w:pPr><w:p w:rsidR="0093632F" w:rsidRDefault="0093632F"><w:pPr><w:rPr></w:rPr></w:pPr><w:r><w:rPr></w:rPr><w:br/><w:t>${test}</w:t></w:r></w:p></w:body>

Это то, что я ожидал, что результат будет:

<w:p w:rsidR="0093632F" w:rsidRDefault="0093632F"><w:pPr><w:rPr></w:rPr></w:pPr><w:r><w:rPr></w:rPr><w:br/><w:t>${test}</w:t></w:r></w:p>

но вместо этого это то, что возвращается

<w:p w:rsidRDefault="00271ADB"/><w:p w:rsidR="00C15291"><w:pPr><w:p w:rsidR="0093632F" w:rsidRDefault="0093632F"><w:pPr><w:rPr></w:rPr></w:pPr><w:r><w:rPr></w:rPr><w:br/><w:t>${test}</w:t></w:r></w:p>

Это результат в редакторе: http://i.imgur.com/HKSYdY8.png

И это результат, который я ожидаю: http://i.imgur.com/8HmThRb.png

1 ответ

Решение

Вам придется изменить первый .*? в повторную группу с отрицательным взглядом. Вы также должны заметить, что я добавил \s после <w:p, это так <w:pPr не подходит Если у вас есть некоторые <w:p> В некоторых случаях вам может потребоваться изменить это на <w:p(?:\s|>),

<w:p\s(?:(?!<w:p\s).)*?\$\{test\}.*?\/w:p>

демонстрация


RegEx совпадает слева направо, поэтому нет никакого реального способа сказать "ленивый раньше". Вместо .*? я использовал (?:(?!<w:p\s).)*?, Давайте разберемся с этим:

(?:         (?# begin non-capturing group for grouping/repetition)
  (?!       (?# begin negative lookahead)
    <w:p\s  (?# no <w:p ahead)
  )         (?# end negative lookahead)
  .         (?# match any character)
)*?         (?# lazy repetition)

Как это работает, как только мы подходим <w:p\s, мы входим в группу без захвата / повторения. Это делает утверждение нулевой длины, чтобы убедиться, <w:p\s не существует до этой точки, а затем соответствует символу. Это лениво повторяется, пока мы не нажмем ${test}, Если выражение видит <w:p\s в перспективе, он потерпит неудачу.. и новое совпадение начнется резервное копирование, сопоставляя это <w:p\s в начале (и начинает делать больше перспектив).

Другие вопросы по тегам