2

我正在尝试构建一个基本的模板引擎。就像已经以开源形式提供的模板引擎一样,我正在使用搜索和替换技术。

然而,由于搜索和替换必须是硬编码的,它就没有那么灵活了。我的意思是,作为一个例子,我正在使用这样的东西

$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. 

4

3 回答 3

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;
于 2011-04-28T07:34:17.590 回答
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-_]意味着它将匹配字母数字字符、连字符或下划线。

(也许有人可以解释为什么使用.可能是一个坏主意?我不是 100% 确定)。

于 2011-04-28T07:37:59.883 回答
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;
于 2011-04-28T10:23:13.680 回答