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

Возврат: обзор

Когда жадный квантификатор «выходит за пределы», движок выполняет возврат: он отступает, пробует другую конфигурацию, повторяет попытку. На простых выкройках это является невидимым; на плохо написанных шаблонах оно может стать экспоненциальным и заморозить браузер на несколько секунд. Это корень ReDoS (Обычный выражение «отказ в обслуживании»).

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». Затем //, затем \\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 попыток