Уроки модуля (4/4)
Возврат: обзор
Когда жадный квантификатор «выходит за пределы», движок выполняет возврат: он отступает, пробует другую конфигурацию, повторяет попытку. На простых выкройках это является невидимым; на плохо написанных шаблонах оно может стать экспоненциальным и заморозить браузер на несколько секунд. Это корень ReDoS (Обычный выражение «отказ в обслуживании»).
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+)+), количество конфигураций
попытка может взорваться.
Катастрофические закономерности
Pattern: (a+)+b
Sample: aaaaaaaaaaaaaaaaaaaaaНет завершающего b → шаблон не работает, но движок пытается попасть туда каждый раз.
возможный раздел as. Экспоненциальный рост: с 30 a вы можете
ждать несколько часов.
Опасности возврата и ReDoS
Если шаблон содержит перекрывающиеся или вложенные квантификаторы (например, (a+)+), механизм оценивает экспоненциальное количество путей, прежде чем произойдет сбой. Замена общих подстановочных знаков исключением классов символов значительно сокращает пути возврата.
Попробуйте это
Извлекайте содержимое между квадратными скобками для каждого вхождения в текст. Используйте ленивую версию квантификатора, чтобы не переходить к более поздним закрытиям.
Показать подсказку
\\[.*?\\] останавливается при первом закрытии ]: без тяжелого возврата.
Решение доступно после 3 попыток
Обзор упражнения
Найдите в тексте каждый URL-адрес `http://...` или `https://...`, используя квантор `?` для необязательных `s` и `\\S+` для непробельных символов пути.
Показать подсказку
https? означает «http», за которым следует необязательная «s». Затем //, затем \\S+ (без пробелов).
Решение доступно после 3 попыток
Дополнительная задача
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 попыток