Перейти до основного вмісту
Модуль 2 · Урок 4 із 48/32 у курсі~12 min
Модульні уроки (4/4)

Відстеження: огляд

Коли жадібний квантор «виходить за межі», механізм виконує зворотне відстеження: він робить крок назад, пробує іншу конфігурацію, повторює спробу. На простих викрійках нім є невидимим; на погано написаних шаблонах він може стати експоненціальним і заморозити браузер на секунди. Це корінь ReDoS (Regular вираз Відмова в обслуговуванні).

Code
Pattern: .*\d
Sample:  abc123def
Steps:
  1.  .*  consumes everything: "abc123def"
  2.  \d  fails (end of string).
  3.  Backtrack: .* drops 'f' -> "abc123de", \d fails on 'f'.
  4.  Backtrack: .* drops 'ef' -> "abc123d", \d fails on 'e'.
  5.  ... and so on until \d finds a digit: match = "abc123" + "?"... actually
       the pattern matches "abc123" because .* leaves "def" and \d looks at '3'? No: the
       backtrack continues and .* ends up being "abc12", \d=3.  Final match: "abc123".

Механізм завжди потрапляє туди, але якщо жадібний квантифікатор містить інший жадібний квантифікатор (наприклад, (a+)+), кількість конфігурацій спробувати може вибухнути.

Катастрофічні моделі

Code
Pattern: (a+)+b
Sample:  aaaaaaaaaaaaaaaaaaaaa

Немає завершення b → шаблон не вдається, але механізм намагається потрапити туди щоразу можливий розділ as. Експоненціальне зростання: з 30 a ви можете чекати годинами.

Небезпека зворотного відстеження та ReDoS

Якщо шаблон містить квантори, що перекриваються, або вкладені квантифікатори (наприклад, (a+)+), система оцінює експоненціальну кількість шляхів, перш ніж дати збій. Заміна загальних символів підстановки на класи символів, що виключають, значно скорочує шляхи зворотного відстеження.

Спробуйте

вправи#regex.m2.l4.e1
Спроби: 0Завантаження…

Витягніть вміст у квадратні дужки для кожного входження в тексті. Використовуйте відкладену версію квантора, щоб уникнути переходу до пізнішого закриття.

Завантаження редактора…
Показати підказку

\\[.*?\\] зупиняється на першому закритті ]: немає важкого повернення назад.

Рішення доступне після 3 спроб

Повторна вправа

вправи#regex.m2.l4.e2
Спроби: 0Завантаження…

Знайдіть у тексті кожну URL-адресу `http://...` або `https://...`, використовуючи квантифікатор `?` для необов’язкового `s` та `\\S+` для непробілів у шляху.

Завантаження редактора…
Показати підказку

https? означає 'http', за яким слід необов'язковий ''. Потім //, потім \\S+ (не пробіли).

Рішення доступне після 3 спроб

Додатковий виклик

вправи#regex.m2.l4.e3
Спроби: 0Завантаження…

Match strings enclosed in double quotes, avoiding excessive backtracking by using the negated class `[^"]*` instead of `.*`.

Завантаження редактора…
Показати підказку

Replace the dot with the negated class [^"] to restrict the engine's backtracking paths.

Рішення доступне після 3 спроб