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

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

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

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

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

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

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

Ответы [ 5 ]

27 голосов
/ 27 января 2012

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

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

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

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

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

11 голосов
/ 27 июля 2012

Эй, если вы не используете переменную 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>'

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

4 голосов
/ 27 января 2012

То, что сказала Эмбер, верно, но вы можете обойти это другим подходом: группа без захвата скобок

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

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

0 голосов
/ 21 октября 2013

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

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

Таким образом, чтобы получить группу 2, «пример», $2 для регулярного выражения или \2, если вы используете строку формата (например, для re.sub) в Python *

0 голосов
/ 27 января 2012

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

...