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-й альтернативе
foo
затем потерпите неудачу какs
не сразу следуетfoots
и вернуться к его 2-й альтернативе; - соответствует 2-й альтернативе
foot
, а затем преуспеть какs
немедленно следует вfoots
и остановись.
- соответствовать его 1-й альтернативе
Некоторые ресурсы
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 - это решение Два.