0 added
0 removed
Original
2026-01-01
Modified
2026-02-26
1
<p>Большинство реализаций регулярных выражений поддерживают две полезные функции:</p>
1
<p>Большинство реализаций регулярных выражений поддерживают две полезные функции:</p>
2
<ul><li>Просмотр вперед - опережающий поиск (<em>lookahead</em>)</li>
2
<ul><li>Просмотр вперед - опережающий поиск (<em>lookahead</em>)</li>
3
<li>Просмотр назад - ретроспективный поиск (<em>lookbehind</em>)</li>
3
<li>Просмотр назад - ретроспективный поиск (<em>lookbehind</em>)</li>
4
</ul><p>В этом уроке мы рассмотрим, зачем они нужны.</p>
4
</ul><p>В этом уроке мы рассмотрим, зачем они нужны.</p>
5
<p>У нас есть следующее регулярное выражение, которое находит две подстроки:</p>
5
<p>У нас есть следующее регулярное выражение, которое находит две подстроки:</p>
6
<p>/LudovicXVI/</p>
6
<p>/LudovicXVI/</p>
7
<p>LudovicXV, LudovicXVI, LudovicXVIII, LudovicLXVII, LudovicXXL</p>
7
<p>LudovicXV, LudovicXVI, LudovicXVIII, LudovicLXVII, LudovicXXL</p>
8
<p>Предположим, что нам не нужно включать в результаты поиска часть подстроки с римскими цифрами XVI. Для этого обернем цифру вот в такую конструкцию:</p>
8
<p>Предположим, что нам не нужно включать в результаты поиска часть подстроки с римскими цифрами XVI. Для этого обернем цифру вот в такую конструкцию:</p>
9
<p>/Ludovic(?=XVI)/</p>
9
<p>/Ludovic(?=XVI)/</p>
10
<p>LudovicXV, LudovicXVI, LudovicXVIII, LudovicLXVII, LudovicXXL</p>
10
<p>LudovicXV, LudovicXVI, LudovicXVIII, LudovicLXVII, LudovicXXL</p>
11
<p>Как мы видим, условия сопоставления, заданные первоначальным выражением, не изменились. Сопоставились те же подстроки, что и в предыдущем примере.</p>
11
<p>Как мы видим, условия сопоставления, заданные первоначальным выражением, не изменились. Сопоставились те же подстроки, что и в предыдущем примере.</p>
12
<p>Однако символы XVI в совпавших подстроках не были включены в окончательный результат поиска. Такое поведение называется<strong>позитивным просмотром вперед</strong>или<strong>позитивным опережающим поиском</strong>.</p>
12
<p>Однако символы XVI в совпавших подстроках не были включены в окончательный результат поиска. Такое поведение называется<strong>позитивным просмотром вперед</strong>или<strong>позитивным опережающим поиском</strong>.</p>
13
<p>Логику позитивного просмотра вперед можно описать следующим образом. Регулярное выражение a(?=b) находит совпадения таких a, за которыми следует b, при этом не делая b частью сопоставления.</p>
13
<p>Логику позитивного просмотра вперед можно описать следующим образом. Регулярное выражение a(?=b) находит совпадения таких a, за которыми следует b, при этом не делая b частью сопоставления.</p>
14
<p>Просмотр вперед также может быть негативным. Тогда он будет искать совпадения в тех подстроках, где указанная в скобках часть подстроки отсутствует. В нашем случае, это по-прежнему XVI. Чтобы из позитивного просмотра сделать негативный, заменим символ = на !.</p>
14
<p>Просмотр вперед также может быть негативным. Тогда он будет искать совпадения в тех подстроках, где указанная в скобках часть подстроки отсутствует. В нашем случае, это по-прежнему XVI. Чтобы из позитивного просмотра сделать негативный, заменим символ = на !.</p>
15
<p>Теперь у нас сопоставились три другие подстроки:</p>
15
<p>Теперь у нас сопоставились три другие подстроки:</p>
16
<p>/Ludovic(?!XVI)/</p>
16
<p>/Ludovic(?!XVI)/</p>
17
<p>LudovicXV, LudovicXVI, LudovicXVIII, LudovicLXVII, LudovicXXL</p>
17
<p>LudovicXV, LudovicXVI, LudovicXVIII, LudovicLXVII, LudovicXXL</p>
18
<p>Кроме просмотра вперед, существует просмотр назад или ретроспективный поиск. Он работает похожим образом, но ищет совпадения символов, расположенных после сгруппированной в скобках части регулярного выражения, которая не будет включена в сопоставление.</p>
18
<p>Кроме просмотра вперед, существует просмотр назад или ретроспективный поиск. Он работает похожим образом, но ищет совпадения символов, расположенных после сгруппированной в скобках части регулярного выражения, которая не будет включена в сопоставление.</p>
19
<p>Иными словами, при позитивном просмотре назад регулярное выражение (?<=b)a находит совпадения таких a, перед которыми находится b, не делая b частью сопоставления.</p>
19
<p>Иными словами, при позитивном просмотре назад регулярное выражение (?<=b)a находит совпадения таких a, перед которыми находится b, не делая b частью сопоставления.</p>
20
<p>Для позитивного просмотра назад используется дополнительный знак <. В этом примере мы находим совпадения подстрок Two, перед которыми следует One:</p>
20
<p>Для позитивного просмотра назад используется дополнительный знак <. В этом примере мы находим совпадения подстрок Two, перед которыми следует One:</p>
21
<p>/(?<=One )Two/</p>
21
<p>/(?<=One )Two/</p>
22
<p>One Two, Three Two</p>
22
<p>One Two, Three Two</p>
23
<p>Чтобы изменить позитивный просмотр назад на негативный, меняем = на !:</p>
23
<p>Чтобы изменить позитивный просмотр назад на негативный, меняем = на !:</p>
24
<p>/(?<!One )Two/</p>
24
<p>/(?<!One )Two/</p>
25
<p>One Two, Three Two</p>
25
<p>One Two, Three Two</p>
26
26