# Чёрная дыра бэктрекинга [todo]
Некоторые регулярные выражения, с виду являясь простыми, могут выполняться оооочень долго, и даже подвешивать браузер.
[cut]
Например, попробуйте пример ниже в Chrome или IE (осторожно, подвесит браузер!):
```js
//+ run
alert( '123456789012345678901234567890z'.match(/(\d+)*$/) );
```
Некоторые движки регулярных выражений (Firefox) справляются с таким регэкспом, а некоторые (IE, Chrome) -- нет.
В чём же дело, что не так с регэкспом?
Да с регэкспом-то всё так, синтаксис вполне допустимый. Проблема в том, как выполняется поиск по нему.
Для краткости рассмотрим более короткую строку: 1234567890z
:
\d+
. Плюс +
является жадным по умолчанию, так что он хватает все цифры, какие может.
Затем движок пытается применить звёздочку вокруг скобок (\d+)*
, но больше цифр нет, так что звёздочка не даёт повторений.
После этого в паттерне остаётся $
, а в тексте -- символ z
.
+
отступает на один символ (бэктрекинг, зелёная стрелка на рисунке выше).
\d+
содержит всё число, кроме последней цифры. Затем движок снова пытается найти совпадение, уже с новой позиции (`9`).
Звёздочка (\d+)*
теперь может быть применена -- она даёт ещё одно число 9
:
\d+
будет содержать 8 цифр, а остаток строки 90
становится вторым \d+
:
$
.
Поисковой движок снова должен отступить назад. При этом последний жадный квантификатор отпускает символ. В данном случае это означает, что укорачивается второй \d+
, до одного символа 9
.
\d+
:
\d+
отступили по-максимуму, так что сокращается снова первое число.
\d+
. Поисковой движок видит место для второго \d+
, теперь уже с позиции 8:
\d+
отступает назад....
\d+
в числе. А их много.\d+
на \d+?
и посмотрим (аккуратно, может подвесить браузер):
```js
//+ run
alert( '123456789012345678901234567890z'.match(/(\d+?)*$/) );
```
Не помогло!
**Ленивые регулярные выражения делают то же самое, но в обратном порядке.**
Просто подумайте о том, как будет в этом случае работать поисковой движок.
Некоторые движки регулярных выражений, например Firefox, содержат хитрые проверки, в дополнение к алгоритму выше, которые позволяют избежать бесконечного перебора или кардинально ускорить его, но все движки и не всегда.