Regex lookahead, lookbehind и атомные группы

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

(?!) - negative lookahead
(?=) - positive lookahead
(?<=) - positive lookbehind
(?<!) - negative lookbehind

(?>) - atomic group

5 ответов

Решение

Примеры

Учитывая строку foobarbarfoo:

bar(?=bar)     finds the 1st bar ("bar" which has "bar" after it)
bar(?!bar)     finds the 2nd bar ("bar" which does not have "bar" after it)
(?<=foo)bar    finds the 1st bar ("bar" which has "foo" before it)
(?<!foo)bar    finds the 2nd bar ("bar" which does not have "foo" before it)

Вы также можете объединить их:

(?<=foo)bar(?=bar)    finds the 1st bar ("bar" with "foo" before it and "bar" after it)

Определения

Смотри вперед позитивно (?=)

Найдите выражение A, за которым следует выражение B:

A(?=B)

Смотри вперед негатив (?!)

Найдите выражение A, где выражение B не следует:

A(?!B)

Смотреть за позитивом (?<=)

Найдите выражение A, где предшествует выражение B:

(?<=B)A

Смотреть за минусом (?<!)

Найдите выражение A, где выражение B не предшествует:

(?<!B)A

Атомные группы (?>)

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

  • (?>foo|foot)s применительно к foots будет соответствовать его 1-й альтернативе fooзатем потерпите неудачу как s не следует сразу, а останавливается, так как обратный ход отключен

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

  • (foo|foot)s применительно к foots будут:

    1. соответствовать его 1-й альтернативе fooзатем потерпите неудачу как s не сразу следует footsи вернуться к его 2-й альтернативе;
    2. соответствует 2-й альтернативе foot, а затем преуспеть как s немедленно следует в footsи остановись.

Некоторые ресурсы

Lookarounds - это утверждения нулевой ширины. Они проверяют регулярное выражение (вправо или влево от текущей позиции - на основе впереди или сзади), успешно или не удается, когда найдено совпадение (на основании положительного или отрицательного значения), и отбрасывают совпадающую часть. Они не потребляют никаких символов - совпадение с регулярным выражением, следующее за ними (если оно есть), начнется с той же позиции курсора.

Читайте регулярно-expression.info для более подробной информации.

  • Позитивный взгляд:

Синтаксис:

(?=REGEX_1)REGEX_2

Совпадение только в случае совпадения REGEX_1; после сопоставления REGEX_1 совпадение отбрасывается, и поиск REGEX_2 начинается с той же позиции.

пример:

(?=[a-z0-9]{4}$)[a-z]{1,2}[0-9]{2,3}

REGEX_1 это [a-z0-9]{4}$ который соответствует четырем буквенно-цифровым символам, за которыми следует конец строки.
REGEX_2 - это [a-z]{1,2}[0-9]{2,3} которая соответствует одной или двум буквам, за которыми следуют две или три цифры.

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

  • Отрицательный взгляд

Синтаксис:

(?!REGEX_1)REGEX_2

Совпадение только если REGEX_1 не совпадает; после проверки REGEX_1 поиск REGEX_2 начинается с той же позиции.

пример:

(?!.*\bFWORD\b)\w{10,30}$

Предварительная часть проверяет наличие FWORD в строке и терпит неудачу, если он находит это. Если не находит FWORDпредварительный просмотр завершается успешно, и следующая часть проверяет, что длина строки составляет от 10 до 30 и содержит только слова a-zA-Z0-9_

Взгляд назад похож на прогноз вперед: он просто смотрит позади текущей позиции курсора. Некоторые разновидности регулярных выражений, такие как javascript, не поддерживают косвенные утверждения. И большинство разновидностей, которые его поддерживают (PHP, Python и т. Д.), Требуют, чтобы эта часть просмотра имела фиксированную длину.

  • Атомные группы в основном отбрасывают / забывают последующие токены в группе, когда токен совпадает. Проверьте эту страницу для примеров атомных групп

Почему? Предположим, вы играете в wordle и ввели «муравей». (да слово из трех букв, это только пример - остынь)

Ответ возвращается пустым, желтым, зеленым, и у вас есть список трехбуквенных слов, которые вы хотите использовать для поиска с помощью регулярного выражения? Как бы вы это сделали?

Для начала вы можете начать с наличия t в третьей позиции:

      [a-z]{2}t

Мы могли бы улучшить, отметив, что у нас нет

      [b-z]{2}t

Мы могли бы еще улучшить, сказав, что в поиске должно быть n.

      (?=.*n)[b-z]{2}t

или разбить его;

(?=.*n) - Загляните вперед и убедитесь, что в совпадении есть n, перед этим n может быть ноль или более символов.

[bz]{2} – две буквы, отличные от "а", в первых двух позициях;

т - буквально "т" в третьей позиции

Я использовал просмотр назад, чтобы найти схему, и просмотр вперед, чтобы найти отсутствующие таблицы с (nolock)

      expression="(?<=DB\.dbo\.)\w+\s+\w+\s+(?!with\(nolock\))"

matches=re.findall(expression,sql)
for match in matches:
    print(match)

Гроккинг смотрит вокруг быстро.
Как различить взгляд вперед и назад? Возьмите 2-минутный тур со мной:

(?=) - positive lookahead
(?<=) - positive lookbehind

предполагать

    A  B  C #in a line

Теперь мы спрашиваем B, где ты?
У B есть два решения, чтобы объявить это местоположение:

Во-первых, B имеет A впереди и C bbind
Во-вторых, B впереди (взгляд вперед) C и позади (взгляд сзади) A.

Как мы видим, задние и передние противоположны в двух решениях.
Regex - это решение Два.

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