Большинство реализаций регулярных выражений поддерживают две полезные функции:
- Просмотр вперед — опережающий поиск (lookahead)
- Просмотр назад — ретроспективный поиск (lookbehind)
В этом уроке мы рассмотрим, зачем они нужны.
У нас есть следующее регулярное выражение, которое находит две подстроки:
/LudovicXVI/
LudovicXV, LudovicXVI, LudovicXVIII, LudovicLXVII, LudovicXXL
Предположим, что нам не нужно включать в результаты поиска часть подстроки с римскими цифрами XVI. Для этого обернем цифру вот в такую конструкцию:
/Ludovic(?=XVI)/
LudovicXV, LudovicXVI, LudovicXVIII, LudovicLXVII, LudovicXXL
Как мы видим, условия сопоставления, заданные первоначальным выражением, не изменились. Сопоставились те же подстроки, что и в предыдущем примере.
Однако символы XVI в совпавших подстроках не были включены в окончательный результат поиска. Такое поведение называется позитивным просмотром вперед или позитивным опережающим поиском.
Логику позитивного просмотра вперед можно описать следующим образом. Регулярное выражение a(?=b) находит совпадения таких a, за которыми следует b, при этом не делая b частью сопоставления.
Просмотр вперед также может быть негативным. Тогда он будет искать совпадения в тех подстроках, где указанная в скобках часть подстроки отсутствует. В нашем случае, это по-прежнему XVI. Чтобы из позитивного просмотра сделать негативный, заменим символ = на !.
Теперь у нас сопоставились три другие подстроки:
/Ludovic(?!XVI)/
LudovicXV, LudovicXVI, LudovicXVIII, LudovicLXVII, LudovicXXL
Кроме просмотра вперед, существует просмотр назад или ретроспективный поиск. Он работает похожим образом, но ищет совпадения символов, расположенных после сгруппированной в скобках части регулярного выражения, которая не будет включена в сопоставление.
Иными словами, при позитивном просмотре назад регулярное выражение (?<=b)a находит совпадения таких a, перед которыми находится b, не делая b частью сопоставления.
Для позитивного просмотра назад используется дополнительный знак <. В этом примере мы находим совпадения подстрок Two, перед которыми следует One:
/(?<=One )Two/
One Two, Three Two
Чтобы изменить позитивный просмотр назад на негативный, меняем = на !:
/(?<!One )Two/
One Two, Three Two
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.