Регулярное выражение Lookbehind не работает с квантификаторами ('+' или '*') - программирование
Подтвердить что ты не робот

Регулярное выражение Lookbehind не работает с квантификаторами ('+' или '*')

Я пытаюсь использовать lookbehinds в регулярном выражении, и он не работает так, как я ожидал. Итак, это не мое реальное использование, но для упрощения я приведу пример. Представьте, что я хочу сопоставить "пример" строки, которая говорит "это пример". Итак, согласно моему пониманию lookbehind, это должно работать:

(?<=this\sis\san\s*?)example

Что это должно сделать, так это найти "это", затем пробельные символы и, наконец, сопоставить слово "пример". Теперь это не работает, и я не понимаю, почему, невозможно ли использовать "+" или "*" внутри lookbehinds?

Я также пробовал эти два, и они работают правильно, но не выполняют моих потребностей:

(?<=this\sis\san\s)example
this\sis\san\s*?example

Я использую этот сайт для проверки своих регулярных выражений: http://gskinner.com/RegExr/

4b9b3361

Ответ 1

Многие библиотеки регулярных выражений допускают использование только строгих выражений для поиска за такими утверждениями, как:

  • соответствуют только строки одной и той же фиксированной длины: (?<=foo|bar|\s,\s) (по три символа)
  • соответствуют только строки фиксированной длины: (?<=foobar|\r\n) (каждая ветвь с фиксированной длиной)
  • соответствуют только строкам с верхней длиной: (?<=\s{,4}) (до четырех повторений)

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

Другая причина может заключаться в том, чтобы избежать попыток авторов создавать слишком сложные регулярные выражения, которые тяжелы для обработки, поскольку они имеют так называемое патологическое поведение (см. также ReDoS).

См. также раздел об ограничениях утверждений внешнего вида на Regular-Expressions.info.

Ответ 2

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

Этот сайт хорошо объясняет это. http://www.phpfreaks.com/blog/pcre-regex-spotlight-k..

Но в значительной степени, когда у вас есть выражение, которое вы сопоставляете, и вы хотите получить все позади, используя \K, он заставит его начать заново...

Пример:

string = '<a this is a tag> with some information <div this is another tag > LOOK FOR ME </div>'

соответствие /(\<a).+?(\<div).+?(\>)\K.+?(?=\<div)/ приведет к перезапуску регулярного выражения после того, как вы согласитесь с тегом окончания div, чтобы регулярное выражение не включало это в результат. (?=\div) заставит движок получить все перед завершением тега div

Ответ 3

То, что сказал Амбер, верно, но вы можете обойти его с помощью другого подхода: группа не скользящих скобок

(?<=this\sis\san)(?:\s*)example

Это заставляет фиксированную длину смотреть, поэтому он должен работать.

Ответ 4

Большинство движков регулярных выражений не поддерживают выражения переменной длины для утверждений lookbehind.

Ответ 5

Вы можете использовать подвыражения.

(this\sis\san\s*?)(example)

Итак, чтобы получить группу 2, "пример", $2 для regex или \2, если вы используете строку формата (например, для python re.sub)