Regex lookahead, lookbehind и атомные группы
Я нашел эти вещи в своем теле регулярных выражений, но у меня нет понятия, для чего я могу их использовать.
Есть ли у кого-нибудь примеры, чтобы я мог понять, как они работают?
(?!) - negative lookahead
(?=) - positive lookahead
(?<=) - positive lookbehind
(?<!) - negative lookbehind
(?>) - atomic group
Ответы
Ответ 1
Примеры
Учитывая строку 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
не сразу следует, и остановится, поскольку обратный трекинг отключен
Неатомарная группа позволит вернуться назад; если последующее сопоставление не удастся, оно будет возвращаться и использовать альтернативные шаблоны, пока не будет найдено совпадение для всего выражения или не исчерпаны все возможности.
Некоторые ресурсы
Ответ 2
Оценки - это утверждения с нулевой шириной. Они проверяют регулярное выражение (вправо или влево от текущей позиции - на основе вперед или назад), преуспевают или терпят неудачу, когда совпадение найдено (на основе положительного или отрицательного) и отбрасывает согласованную часть. Они не потребляют никакого символа - соответствие для регулярного выражения, следующего за ними (если есть), будет начинаться с одной и той же позиции курсора.
Подробнее читайте regular-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_
Look-behind похож на look-ahead: он просто смотрит за текущую позицию курсора. Некоторые ароматы регулярных выражений, такие как javascript, не поддерживают утверждения look-behind. И большинство ароматов, которые его поддерживают (PHP, Python и т.д.), Требуют, чтобы часть обратного следа имела фиксированную длину.
- Атомные группы в основном отбрасывают/забывают последующие токены в группе после совпадения токенов. Просмотрите эту страницу для примеров атомных групп
Ответ 3
Грохоты быстро исчезают.
Как отличить lookahead и lookbehind? Пройдите 2 минуты тура со мной:
(?=) - positive lookahead
(?<=) - positive lookbehind
предполагать
A B C #in a line
Теперь, мы спрашиваем B, где вы?
B имеет два решения, объявляющих его местоположение:
Один, B имеет A вперед и имеет C bebind
Два, B впереди (lookahead) C и сзади (lookhehind) A.
Как мы видим, в обоих решениях противоположные и дальнейшие противоположны.
Regex - это решение Two.