Парсинг вложенных тегов

Фанат

oncle terrible
Команда форума
Имеем самопальный маркап с вложенными тегами.
Код:
"post text
<!--quote-->quote1<!--quote-->sub-quote1<!--/quote--><!--/quote-->
post text
<!--quote-->quote2<!--/quote-->
post text
";
Что-то меня клинит.

Жадный поиск забирает все цитаты целиком.
Не жадный поиск оставляет кусок внешней цитаты не захваченным.
Рекурсивный поиск (.*?|?R)рушит мне систему. Возможно, надо задавать более специфичный паттерн вместо .*?

Какие есть еще варианты?
 
Последнее редактирование:

Ирокез

бессмертный пони
Команда форума
Партнер клуба
PHP:
preg_split('/<!--.*?-->/sim', $subject); // Не решит проблему?
 

Фанат

oncle terrible
Команда форума
Не могу сообразить, как использовать. Как потом отличить вложенную цитату от текста?
 

Ирокез

бессмертный пони
Команда форума
Партнер клуба
Не могу сообразить, как использовать. Как потом отличить вложенную цитату от текста?
PHP:
preg_match('/(?:(.*?)<!--.*?-->)|(.*)/sim', $subject)

я давно пользуюсь утилитой RegexBuddy (не сочтите рекламой)
 

fixxxer

К.О.
Партнер клуба
Мне кажеццо, проще как-то вроде preg_split('/(?=<!--\/?quote-->)/si', $subject) и счетчик вложенности потом.

С рекурсией и preg_replace_callback можно еще (хотя зависит от того, что требуется получить), но это надо голову поломать.
 

Фанат

oncle terrible
Команда форума
Мне кажеццо, проще как-то вроде preg_split('/(?=<!--\/?quote-->)/si', $subject) и счетчик вложенности потом.
Все равно не понимаю. оно мне вернет кучу текстовых отрезков. как потом понять, кто из них просто текст, а кто - цитата?
Впрочем, если захватывать и делимитер и потом на него смотреть...
С рекурсией и preg_replace_callback можно еще (хотя зависит от того, что требуется получить), но это надо голову поломать.
Вот я и ломаю. Казалось бы, должна быть стандартная задача с кучей готовых решений, но блин.
Рекурсия хорошо, но для нее надо захватывать цитату целиком, а она, в случае вложенной, не зохавываецца :( Точнее зохавываецца не до конца.
 

Ирокез

бессмертный пони
Команда форума
Партнер клуба
Это потом натравливать на элементы полученного массива? Или это другой вариант решения изначальной задачи?
изначальный, ну и да не preg_match, а preg_match_all

https://drive.google.com/open?id=0B1kOEX54dd2kZTNCQ1ZEcXN5WjA

1 и 2 группа содержат текст, если добавить группу <!--(/)?.*?-->, то открывающий закрывающий получишь, ну или варианты <!--(*.?)-->

в любом случае нужен будет цикл, если использовать _callback, то сразу можно в один проход получить массив
 
Последнее редактирование:

Фанат

oncle terrible
Команда форума
изначальный, ну и да не preg_match, а preg_match_all
У меня получается такое.
Код:
  array(8) {
    [0]=>
    string(25) "post text 1<!--quote-->"
    [1]=>
    string(18) "quote1<!--quote-->"
    [2]=>
    string(23) "sub-quote1<!--/quote-->"
    [3]=>
    string(13) "<!--/quote-->"
    [4]=>
    string(27) "post text 2<!--quote-->"
    [5]=>
    string(19) "quote2<!--/quote-->"
    [6]=>
    string(15) "post text 3"
    [7]=>
    string(0) ""
  }
снова не соображу, как потом это собирать. Писать лексер со счетчиком открытых и закрытых тегов?
 

ksnk

прохожий
Ну вот, "рабочий" пример. Готовый тег с обработанными вложенностями, присутствует в строке 26, там где sprintf
 

ksnk

прохожий
Ну, почти из головы ;) Я таким образом свой шаблонизатор парсил как-то...
 

Ирокез

бессмертный пони
Команда форума
Партнер клуба
У меня получается такое.
Код:
  array(8) {
    [0]=>
    string(25) "post text 1<!--quote-->"
    [1]=>
    string(18) "quote1<!--quote-->"
    [2]=>
    string(23) "sub-quote1<!--/quote-->"
    [3]=>
    string(13) "<!--/quote-->"
    [4]=>
    string(27) "post text 2<!--quote-->"
    [5]=>
    string(19) "quote2<!--/quote-->"
    [6]=>
    string(15) "post text 3"
    [7]=>
    string(0) ""
  }
снова не соображу, как потом это собирать. Писать лексер со счетчиком открытых и закрытых тегов?

http://ideone.com/siihcl
 
Сверху