Есть свой шаблонизатор все работает отлично, но проблема постоянно возникает с логикой IF/ELSE, причина понятна слабовато знаю PCRE. Я использую вот такое выражение для поиска тегов типа <if name="var">$VAR = TRUE</if>, есть ещё вариант <if name="var">$VAR = TRUE</else>$VAR = FALSE</if>. Сами по себе они работаю, но вот если начитаются вложения типа: Код (Text): <if name="var"> <if name="var2"> </else> </if> </if> То начинаются и проблемы, при полной жадности он кушает: <if name="var"><if name="var2"> </else> </if> что понятно. вот выражение: Код (Text): |<if name="'.$var.'">(.*)</if>|sim При ограниченной типа: Код (Text): <if name="'.$var.'">(.*?)</if>.|sim тоже проблемы нельзя что б за </if> что-то стояло. вот еше для if/else: Код (Text): |<if name="'.$var.'">(.*?)</else>(.*?)</if>|sim На данный момент решаю проблему парся два раза в зависимости есть ли в квантификаторах: <if name=" Вот код метода: PHP: /** * ПАРСИНГ <if name="">*</if> * */ protected function if_($var, $value=false){ if(!preg_match('|<if name="'.$var.'">(.*?)</if>.|sim', $this->CONTENT, $result) or stristr($result[1],'</else>')){ $result =false; } if($result and stristr($result[1],'<if name="')){ if(!preg_match('|<if name="'.$var.'">(.*)</if>.|sim', $this->CONTENT, $result) ){ $result =false; } } if($result and !empty($result)){ if($value){ $this->put(str_replace($result[0],$result[1],$this->CONTENT)); }else{ $this->put(str_replace($result[0],'',$this->CONTENT)); } } } И даже так частенько происходят накладки с вложениями условиями (( Хотелось бы как-то сделать один нормальный PCRE шаблон чтобы отбрасывать такие ситуации. Может кто сталкивался или видел в каком-то шаблонизаторе нормальное выражение. Пожалуйста не рекомендуйте свои шаблонизаторы, вопрос состоит не в том какой шаблонизатор выбрать. Приму и не проверенные регулярки сам проверю.
у тебя принцип неверный ты обрабатываешь блоками, а куда проще было бы обрабытвать выражениями короче говоря сначала делаешь проверку на синтаксис(нет ли где незакрытых тегов и тд) а потом обрабатываешь выражения(<if><esle><elseif></if> и тд)
Вложенность реализовывается наипростейшим образом: PHP: <? $conditions = '<if name="Apple"><div><if age="24">Hi</if></div></if>'; /** * Реализовываем вложенную логику */ // Строка с регуляркой // Мы намеренно используем жадные модификаторы $pattern = '/<if>(.+)<\/if>/is'; while(preg_match($pattern, $conditions)) { $conditions = preg_replace($pattern, 'if($name = "Apple") { echo $1; }', $conditions); } ?>
Код (Text): <if name="Apple"><div><if age="24">Hi</if></div><div><if blabla="123">Hi</if></div></if> а такое разгребёт?
поменять '/<if(.*?)>(.*?)<\/if>/is' и будет и такое разгребать, как Sergey89 показал и работать быстрее.
Пропустив в своём примере вопросительный знак, уменьшающий жадность квантификатора, я не опечатался. То, что ты уменьшил жадность, убивает всю ту логику, которую я построил для вложенности.
Сначала выделить все блоки с помощью preg_match. То есть пробегаемся по всему тексту и ищем ифы, потом для каждого ифа ищем ближайший енд, начиная с последнего, чтобы развернуть всё структуру корректно. Ну а дальше уже евалим условие или что-то ещё с ним делаем.
Есть мнение писать эту логику на конечных автоматах. Но не могу выбрать как бы регулярка будет нагляднее но вот КА будет быстрее, но запутано. Кто бы что предпочол?