PHP: неожиданный PREG_BACKTRACK_LIMIT_ERROR - PullRequest
4 голосов
/ 14 марта 2012

<code>function recursiveSplit($string, $layer) {
    $err = preg_match_all("/\{(([^{}]*|(?R))*)\}/",$string,$matches);
    echo "Elementi trovati: $err<br>";
    if($err == FALSE) echo "preg_match_all ERROR<br>";

    // iterate thru matches and continue recursive split
    if (count($matches) > 1) {
        for ($i = 0; $i < count($matches[1]); $i++) {
            if (is_string($matches[1][$i])) {
                if (strlen($matches[1][$i]) > 0) {
                    echo "<pre>Layer ".$layer.":   ".$matches[1][$i]."

"; recursiveSplit ($ match [1] [$ i], $ layer + 1); } } } } } $ Буфера = "{{aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaa {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}"; recursiveSplit ($ buffer, 0);

выход

Elementi trovati: 
preg_match_all ERROR
Backtrack limit was exhausted!

этот код дает мне ошибку PREG_BACKTRACK_LIMIT_ERROR ... но предел возврата составляет 100.000.000.

Это мой первый раз с регулярным выражением, и я действительно не знаю, как его решить.

Большое спасибо, Marco

1 Ответ

10 голосов
/ 14 марта 2012

Еще один классический случай катастрофического возврата . Должен быть мой счастливый день сегодня.

/\{(([^{}]*|(?R))*)\}/

соответствует, только если фигурные скобки правильно вложены. Которого, конечно, нет в твоей строке.

Теперь проблема в том, что вашему регулярному выражению необходимо выяснить все возможные комбинации строк, которые вы можете построить с помощью 106 a s, чтобы выяснить это, потому что у вас есть вложенные квантификаторы ((...)*)*). Который (поправьте меня, если я ошибаюсь) должен быть где-то около 106!, что доходит до

114628056373470835453434738414834942870388487424139673389282723476762012382449946252660360871841673476016298287096435143747350528228224302506311680000000000000000000000000

, который легко превосходит ваш PREG_BACKTRACK_LIMIT.

Если вы используете собственнические квантификаторы , чтобы убедиться, что вы никогда не вернетесь к уже не сопоставленным фигурным скобкам, тогда у вас должно быть все в порядке:

/\{(([^{}]*+|(?R))*)\}/
...