我正在尝试构建一个基本的模板引擎。就像已经作为开源提供的模板引擎一样,我正在使用搜索和替换技术。
但是,由于搜索和替换必须是硬编码的,因此它不是那么灵活。我的意思是,作为一个例子,我正在使用这样的东西
$templateMarkup = '<div class="title">{_TITLE_}</div>';
$renderedMarkup = str_replace("{_TITLE_}",$title,$templateMarkup);
echo $renderedMarkup;
正如您所看到的,它是硬编码的。因此,我必须故意了解所有占位符以完成成功渲染。
我在正则表达方面有点弱。但我知道,如果我可以开发一个正则表达式,它可以匹配所有以{_
开头并结束_}
的文本并获取它们之间的值,我就可以创建一个灵活的模板引擎。
我需要正则表达式的帮助。
如果我完全走错了路,请警告我。
<子> 对于那些认为我正在重新发明轮子的人。这是我的解释
Templating engines, that are already available are quite unnecessarily complex.
My requirements are simple and so I am builidng my own simple engine.
答案 0 :(得分:2)
除非你试图限制人们在一个模板中可以做什么,并想控制他们可以放入哪个标记,否则我会推荐PHP作为一种漂亮的模板语言!
如果你想坚持你的解决方案,你可以做这样的事情来管理替换。
$template = "foo={_FOO_},bar={_BAR_},title={_TITLE_}\n";
$replacements = array(
'title' => 'This is the title',
'foo' => 'Footastic!',
'bar' => 'Barbaric!'
);
function map($a) { return '{_'. strtoupper($a) .'_}';}
$keys = array_map("map", array_keys($replacements));
$rendered = str_replace($keys, array_values($replacements), $template);
echo $rendered;
答案 1 :(得分:1)
如果您的模板标记只是一个单词,那么您正在寻找的正则表达式为{_(\w+)_}
。你有点像这样使用它:
<?php
$replacements = array(
"firstname" => "John",
"lastname" => "Smith"
);
$template_markup = "Hello {_firstname_} {_lastname_}";
if(preg_match_all('/{_(\w+)_}/', $template_markup, $matches)) {
foreach($matches[1] as $m) {
$template_markup = str_replace("{_".$m."_}", $replacements[$m], $template_markup);
}
}
echo $template_markup;
?>
你会看到preg_match_all
在正则表达式周围有正斜杠,这些都是分隔符。
更新:如果要将正则表达式扩展到单个单词之外,那么在使用.
匹配任何字符时要小心。最好使用类似的东西来指定你想要包含其他字符:{_([\w-_]+)_}
。 [\w-_]
表示它将匹配字母数字字符,连字符或下划线。
(也许有人可以解释为什么使用.
可能是一个坏主意?我不是百分百肯定的。)
答案 2 :(得分:0)
我结合了Sam和James提供的解决方案来创建新的解决方案。
Sam
表示正则表达式部分James
部分 str_replace()
。以下是解决方案:
$replacements = array(
"firstname" => "John",
"lastname" => "Smith"
);
function getVal($val) {
global $replacements;
return $replacements[$val];
}
$template_markup = "Hello {_firstname_} {_lastname_}";
preg_match_all('/{_(\w+)_}/', $template_markup, $matches);
$rendered = str_replace($matches[0], array_map("getVal",array_values($matches[1])), $template_markup);
echo $rendered;