Регулярные выражения и условные конструкции
sometext
[endif]
и/или:
sometext
[endfor]
где (1;2) значит: начинать со значения 1 и делать 2 раза (это так для справки).
Мои безуспешные попытки написать нечто вроде: "/\{if\((.*?)(<=>)(.*?)\)\}\{\endif}/is", ничего не дали. Использую preg_replace_callback($regexp, "if_func", $str);
И не понимаю, что передается в if_func - массив значений или просто несколько значений. Не гуглится как-то ничего путного/похожего.
Заранее благодарен.
во вторых в примерах у тебя элименты закрыты в квадратных скобках[], а в регулярке ты выбираешь фигурные{}
от чегу у тебя ничего и не получается
и при выборе неравенства ты ищешь <=> , а тбе надо одно из трех
соответственно регулярка должна бриобрести подобный вид
и в функции ты получаешь
(
[0] => [if(val1=val2)]
sometext
[endif]
[1] => val1
[2] => =
[3] => val2
[4] =>
sometext
)
{$res='';
//cond[1] - первое значение
//cond[2] - символ сравнения, больше, меньше и т.д.
//cond[3] - второе значение
//cond[4] - содержание
switch($cond[2])
{
case '=':{if($cond[1]==$cond[3])$res=$cond[4]; break;}
case '<': {if($cond[1]<$cond[3])$res=$cond[4]; break;}
case '>': {if($cond[1]>$cond[3])$res=$cond[4]; break;}
case '<=': {if($cond[1]<=$cond[3])$res=$cond[4]; break;}
case '>=': {if($cond[1]>=$cond[3])$res=$cond[4]; break;}
case '<>': {if($cond[1]<>$cond[3])$res=$cond[4]; break;}
}
return($res);
}
$str=file_get_contents('template.html'); //получаем шаблон
$str=preg_replace_callback('/\[if\((.*?)([<=>]{1,2})(.*?)\)\](.*?)\[endif\]/is', 'cond_if',$str); //выполняем преобразование
echo $str; //выводим результат
Теперь буду делать цикл. Результат своих изысканий выложу в этой теме.
P.S. так и думал что Вы предложите Smarty ;)
Для справки: регулярное выражение описывает регулярный контекстно-свободный язык и преобразуется в конечный автомат, который не способен разобрать ваши управляющие конструкции произвольной вложенности. Для разбора вашего языка требуется автомат с магазинной памятью.
Для решения задачи вам потребуется написать собственный парсер или описать грамматику и его вам сгенерирует какой-нибудь инструмент типа bison или coco/r.
В ручную написать не так сложно. Идея тут примерно такая же как и в случае с интерпретатором арифметических выражений. Только для поиска управляющих конструкций в вашем случае вполне можно использовать регулярные выражения. В итоге получится рекурсивный нисходящий парсер.
З.Ы. Могу накидать такой парсер на C#. При условии описания с вашей стороны языковых кострукций. С виду язык напоминает юниксовый макропроцессор m4.
А пока представляю цикл for:
{$res=''; //результирующая строка, изначально пустая
$j=$cond[1]; //начальное значение
while($j<=$cond[2])
{
$j++;
$res=$res.$cond[3]; //добавляем результат
}
return($res); //возвращаем результат
}
$str=file_get_contents('template.html'); //получаем шаблон
$str=preg_replace_callback('/\[for\(([0-9]{1,5});([0-9]{1,5})\)\](.*?)\[endfor\]/is', 'cond_for',$str);
-----UPD
А как можно получить значение переменной по имени, таким образом не получилось:
echo $$somestr;
З.Ы. Могу накидать такой парсер на C#. При условии описания с вашей стороны языковых кострукций. С виду язык напоминает юниксовый макропроцессор m4.
Если Вам не трудно, и Вы не боитесь того, что это станет всем доступно, то пожалуйста выкладывайте в тему, буду благодарен.
Конструкции языка довольно простые:
if-endif:
//круглыми скобками не должно быть пробелов (собственно как и после)
text
[endif]
for:
text
[endfor]
$somevar - подстановка переменной
Разумеется все это будет еще дорабатываться, и в конце концов, будет отдано на всеобщее обозрение.
А как можно получить значение переменной по имени, таким образом не получилось:
echo $$somestr;
Можете попробовать так ${$somestr}
-----UPD
А как можно получить значение переменной по имени, таким образом не получилось:
echo $$somestr;
думаю что проблема в уровне объявления переменных
подозреваю что ты хотел сделать что-то на подобии этого
function func($var_name){
global $$var_name;
echo $$var_name;
}
func("var");
if-endif:
//круглыми скобками не должно быть пробелов (собственно как и после)
text
[endif]
Хмм [else] всетаки необходим.
Не ясно в какой момент вычисляется val1 и val2. Откуда они берутся?
dead_star, я не совсем понял Вас. Мне нужно просто по имени переменной к ней (переменной) обратиться.
Не ясно в какой момент вычисляется val1 и val2. Откуда они берутся?
else подразумевалось в перспективе, а здесь был просто упрощенный вид. Как я понимаю [else] ставить между [if...] и [endif]?
val1 и val2 - это переменные, которые подставляются на раннем этапе разбора шаблона. Также могут быть просто, заранее объявленными значениями либо константами.
Я так раскинул мозгом и придумал "рекурсивный" метод. Объясняю:
функцией preg_match_all с флагом PREG_OFFSET_CAPTURE, получаем все вхождения со смещениями для if, else и endif. Если, допустим, стоят 2 или более if'а подряд, то некий счетчик $rec_lvl увеличиваем, а когда встречаем endif, то уменьшаем.
Изначально придумывалось без [else], а с ним, наверное так: каждому [else] присваивать индекс = $rec_lvl, и на его основании делать выводы.