Парсинг XML на РНР - ошибка, не поддающаяся логике

Обсуждение серверного программирования.

Модераторы: Duncon, Yurich

Ответить
Хыиуду
Сообщения: 2442
Зарегистрирован: 06 мар 2005, 21:03
Откуда: Москва
Контактная информация:

Вопрос мой прост и краток.

Код: Выделить всё

$xml='<Cities> '.str_repeat("<City> <name>Москва</name>   </City>", 7).'  <Cities>';
preg_match_all('~<(.*?)(?:\s+(.*?))?>(.*?)<\/\1>~', $xml, $matches); 
print_r($matches);
Поясняю, что должно делать регулярное выражение - разбивать тег типа <a href="yandex.ru">Яндекс</a> на три части - 'a', 'href="yandex.ru"' и 'Яндекс'. При парсинге этого xml массив $matches должен получаться таким:

Код: Выделить всё

Array
(
    [0] => Array
        (
            [0] => <City> <name>Москва</name>   </City>
            [1] => <City> <name>Москва</name>   </City>
            [2] => <City> <name>Москва</name>   </City>
            [3] => <City> <name>Москва</name>   </City>
            [4] => <City> <name>Москва</name>   </City>
            [5] => <City> <name>Москва</name>   </City>
            [6] => <City> <name>Москва</name>   </City>
        )

    [1] => Array
        (
            [0] => City
            [1] => City
            [2] => City
            [3] => City
            [4] => City
            [5] => City
            [6] => City
        )

    [2] => Array
        (
            [0] => 
            [1] => 
            [2] => 
            [3] => 
            [4] => 
            [5] => 
            [6] => 
        )

    [3] => Array
        (
            [0] =>  <name>Москва</name>   
            [1] =>  <name>Москва</name>   
            [2] =>  <name>Москва</name>   
            [3] =>  <name>Москва</name>   
            [4] =>  <name>Москва</name>   
            [5] =>  <name>Москва</name>   
            [6] =>  <name>Москва</name>   
        )

)
Надо сказать, он именно таким и получается. То же самое, если поставить в str_repeat число, меньшее 7. Но если поставить 8 - регулярное выражение не находит ничего. Экспериментальным путем было выяснено, что чем больше внутренних тегов, тем при меньшем количестве повторов регэксп падает. Например, если заменить повторяемую строку на
<City> <name>Москва</name><year>1147</year>
то ничего не находит уже не при 8, а при 7 повторах.
Я в растерянности

UPD: решение неэлегантное, но простое.
ini_set("pcre.backtrack_limit",10000000);
ini_set("pcre.recursion_limit",10000000);
Искусство программирования - заставить компьютер делать все то, что вам делать лень.
Для "спасибо" есть кнопка "Спасибо" в виде звездочки внизу под ником автора поста.
Ответить