PCRE логика для if/else if

Статус
В этой теме нельзя размещать новые ответы.

TiTanium

Новичок
PCRE логика для if/else if

Есть свой шаблонизатор все работает отлично, но проблема постоянно возникает с логикой IF/ELSE, причина понятна слабовато знаю PCRE. Я использую вот такое выражение для поиска тегов типа <if name="var">$VAR = TRUE</if>, есть ещё вариант <if name="var">$VAR = TRUE</else>$VAR = FALSE</if>. Сами по себе они работаю, но вот если начитаются вложения типа:
Код:
<if name="var">
  <if name="var2"> </else> </if>
</if>
То начинаются и проблемы, при полной жадности он кушает: <if name="var"><if name="var2"> </else> </if> что понятно. вот выражение:
Код:
|<if name="'.$var.'">(.*)</if>|sim
При ограниченной типа:
Код:
<if name="'.$var.'">(.*?)</if>.|sim
тоже проблемы нельзя что б за </if> что-то стояло.
вот еше для if/else:
Код:
  |<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 шаблон чтобы отбрасывать такие ситуации. Может кто сталкивался или видел в каком-то шаблонизаторе нормальное выражение.
 

DiMA

php.spb.ru
Команда форума
забудь этот велосипед как страшный сон :)
поставь Blitz
 

TiTanium

Новичок
DiMA
Извини но вопрос абсолютно в другом, пожалуйста не пишите подобных сообщений. Я прекрасно понимаю зачем мне это надо и что существуют другие шаблонизаторы.
 

cDLEON

Онанист РНРСlub
если ты понимаешь зачем тебе это надо, то будь добр написать сиё дело на конечных автоматах а не на регулярке.

-~{}~ 16.07.09 02:37:

Неужели я таким тоже был :(
На пхп, пхп изобретал)))
 

iceman

говнокодер
<if name="'.$var.'">(.*?)</if>.|sim

тут не должно быть точки =>> .|sim
 

antson

Новичок
Партнер клуба
TiTanium
То что ты сейчас пытаешься сделать - это написать простенький интерпретатор выражений - парсер.

А такую задачу человечество решает с момента появления первых ЭВМ. И прежде чем за нее взяться неплохо было бы
ознакомиться с тем, что же придумали до тебя.

Интерпретаторы же внутри себя имеют логику конечных автоматов, основоположники КА явлются Мили и Мур.
Очень хорошо будет, если ознакомишься с ними и поймешь различие между ними.

Также есть уже разработанные механизмы для описания синтаксиса новых языков(или в частном случае выражений)
которые должен понимать интерпретатор.
Даже есть программы для конктерных языков (для пхп увы не видел), которые по такому формальному описанию генерируют код осуществляющий разбор и выполнение.



новых
 

Alexandre

PHPПенсионер
То что ты сейчас пытаешься сделать - это написать простенький интерпретатор выражений - парсер.

А такую задачу человечество решает с момента появления первых ЭВМ. И прежде чем за нее взяться неплохо было бы ознакомиться с тем, что же придумали до тебя.

Интерпретаторы же внутри себя имеют логику конечных автоматов, основоположники КА явлются Мили и Мур.
пока что из описания синтаксиса формальных языков ( в данном случае парсеров) лучше всего подходит yaz ( дока)
попробуй изобрести велосипед на базе yaz
 

TiTanium

Новичок
antson
PCRE это то конечный автомат у которого есть ещё и кэширование и оптимизация шаблонов он универсален и создан для разбора анализа и разбора текста, да если я напишу на автоматах это будет быстрее работать НО, потом будет тяжело сориентироваться в коде. Меня не интригует само проектирование спасибо за подсказки, но это не то.
 

Alexandre

PHPПенсионер
PCRE это то конечный автомат у которого есть ещё и кэширование и оптимизация шаблонов он универсален и создан для разбора анализа и разбора текста
кэширование и оптимизация шаблонов - ничего не путаешь?
 

TiTanium

Новичок
PHP-машина скрывает этот процесс от пользователя. Функция preg_match () выполняет pcre_compile () и кэширует результат, чтобы избежать его повторной трансляции при последующем выполнении. PCRE-функции реализованы внутри расширения, поэтому обладают большим контролем над выделенной для них памятью, чем PHP-код пользовательского пространства. Это позволяет PCRE-функциям кэшировать транслированные регулярные выражения не только в ходе запроса, но и между запросами. Со временем это полностью устраняет издержки трансляции регулярных выражений. Данная стратегия реализации весьма близка к РНР4-методу кэширования Text_Word-o6beKTOB без использования factory-класса,
это отсюда:
www.hostland.su/books/php/page/289.html
 

TiTanium

Новичок
iceman
Читал спасибо но опыта не хватет чтобы написать чтот болие мение серйозное выражение.
 

Rin

*
Вместо
(.*?)
пишите
Код:
((?>[^<]+|(?!<if\s|</if>).)*+)
Кэширование откомпилированных шаблонов и оптимизация у PCRE действительно есть, но для того чтобы писать скорострельные рег. выражения, всё равно нужно очень хорошо в них разбираться.

Шаблонизатор, написанный c использованием PCRE будет всё равно в разы (в десятки раз) медленнее, чем blitz или PHPTemplate.

Если есть быстрое и отлаженное готовое решение с хорошей функционильностью -- нужно им воспользоваться, а потратить сэкономленное время на что-то более полезное.

~~~~~~~~~~
После </if> пробела нет, его вставляет этот форум.
 

TiTanium

Новичок
Rin
Большое спасибо за помощь, дело в том что шаблонизатор нужен для определеных целей больше для вызова сниппетов, и манипуляциями с модулями, стороние шаблонизаторы такое делать не умеют, а логика IF очень частенько нада, для сложных манипуляций с перемеными там есть php. Ктомуже можно использовать в модуляюх другие шаблонизаторы + есть конечное кеширование.

-~{}~ 16.07.09 10:36:

Rin
<if name="'.$var.'">((?>[^<]+|(?!<if\s|</if>).)*+)</if>|sim
PHP error: Unknown modifier '('

): Пробел убрал

-~{}~ 16.07.09 10:55:

|<if name="'.$var.'">((?>[^<]+|(?!<if\s|</if> ).)*+)</if>|sim
нашол бок надо было так написать:

%<if name="'.$var.'">((?>[^<]+|(?!<if\s|</if> ).)*+)</if>%sim
 

Alexandre

PHPПенсионер
дело в том что шаблонизатор нужен для определеных целей больше для вызова сниппетов, и манипуляциями с модулями, стороние шаблонизаторы такое делать не умеют,
у нас на блице:
- генерятся разные конфиги
в том числе и подключение модулей
- генерятся SQL
- генерятся сами шаблоны

все зависит от умения прикрутить тот или иной продукт
 

TiTanium

Новичок
Alexandre
Все зависит от жилания использовать ))
спасибо Rin ещё раз все работает прекрасно!!! я почти счаслив))
 

nerezus

Вселенский отказник
TiTanium если ты все равно не хочешь читать то, что тебе пишут, то нахрена тему заводишь?

Тебе сказали:
1) Это тебе не нужно(в первых постах)
2) Юзай FSM(в последующих)
http://ru.wikipedia.org/wiki/Конечный_автомат
3) tidy и парсинг XML.
 

TiTanium

Новичок
nerezus
я пришол за конкретным ответом.. я его получил спасибо, а вы вместо того чтоб поумничать хотябы попытальсь бы ответить на конкретный вопрос. И позвольте решать нужно оно или не нужно самому без помощи ок?

-~{}~ 16.07.09 14:34:

%<if name="'.$var.'">((?>[^<]+|(?!<if\s|</if> ).)*+)</if>%sim
Так срабатывает:
<if name="var">
<if name="var2"> </if>
</if>

а вот так нет:
<if name="var">
<if name="var2"> </if>
<if name="var3"> </if>
</if>
 

iceman

говнокодер
сам же сказал что тебе не нужна помощь...

и чем тебя не устраивает
PHP:
<?php if(condition) { ?>expression<?php } else .... ?>
???
 
Статус
В этой теме нельзя размещать новые ответы.
Сверху