在 PHP 中制作一个简单的模板引擎
Making a simple templating engine in PHP
我需要编写一个简单的 PHP 函数来用各自的数据替换 {{ }}
个字符之间的文本。
示例:
字符串:“甚至还有奇怪的万世 {{noun}}
可能 {{verb}}
”
$data = ['noun' => 'bird', 'verb' => 'fly'];
结果:
"甚至 鸟 都可以飞"
我几乎可以使用基于 preg_replace_callback
的以下代码
function compile($str,$data){
foreach ($data as $k => $v) {
$pattern = '/\b(?<!\-)(' . $k . ')\b(?!-)/i';
$str = preg_replace_callback($pattern, function($m) use($v){
return $v;
}, $str);
}
return $str;
}
但我似乎无法解释 {{ }}
。
结果如下所示:
"并且随着奇怪的永世甚至 {{bird}} 可能 {{fly}}"
如何调整正则表达式 and/or 代码以解决双大括号?
此外,在有人问我为什么要尝试手动执行此操作而不是使用 PHP 本身或 Smarty 插件之前——安装插件的用例太窄了,我不能使用 PHP 本身,因为输入字符串作为数据库中的原始文本传入。我需要使用存储在 PHP 数组中的数据来编译原始文本。
您可以使用
$str = "and with strange aeons even {{noun}} may {{verb}}";
$data = ['noun' => 'bird', 'verb' => 'fly'];
$pattern = '/{{(' . implode('|', array_keys($data)) . ')}}/i';
echo preg_replace_callback($pattern, function($m) use($data){
return $data[strtolower($m[1])];
}, $str);
// => and with strange aeons even bird may fly
参见PHP demo。
$pattern
看起来像 /{{(noun|verb)}}/i
,并且会在捕获单词本身时匹配双括号内的 noun
或 verb
。替换将是 $data
数组的相应键值。需要使用 strtolower($m[1])
将第 1 组值变为小写,因为 $data
数组中的键都是小写,并且 $pattern
也可以匹配大写变体。
既然你在循环,请保持简单:
foreach ($data as $k => $v) {
$str = str_ireplace('{{'.$k.'}}', $v, $str);
}
如果需要,您可以在 {{
之前和 }}
之后添加 space。
利用 strtr()
收工:
$string = 'and with strange aeons even {{noun}} may {{verb}}';
$data = ['{{noun}}' => 'bird', '{{verb}}' => 'fly'];
echo strtr( $string, $data );
产生:
and with strange aeons even bird may fly
strtr()
很好,因为它不会在以下情况下弄乱字符串:
$data = ['{{noun}}' => 'bi{{verb}}rd', '{{verb}}' => 'fly'];
我需要编写一个简单的 PHP 函数来用各自的数据替换 {{ }}
个字符之间的文本。
示例:
字符串:“甚至还有奇怪的万世 {{noun}}
可能 {{verb}}
”
$data = ['noun' => 'bird', 'verb' => 'fly'];
结果:
"甚至 鸟 都可以飞"
我几乎可以使用基于 preg_replace_callback
function compile($str,$data){
foreach ($data as $k => $v) {
$pattern = '/\b(?<!\-)(' . $k . ')\b(?!-)/i';
$str = preg_replace_callback($pattern, function($m) use($v){
return $v;
}, $str);
}
return $str;
}
但我似乎无法解释 {{ }}
。
结果如下所示:
"并且随着奇怪的永世甚至 {{bird}} 可能 {{fly}}"
如何调整正则表达式 and/or 代码以解决双大括号?
此外,在有人问我为什么要尝试手动执行此操作而不是使用 PHP 本身或 Smarty 插件之前——安装插件的用例太窄了,我不能使用 PHP 本身,因为输入字符串作为数据库中的原始文本传入。我需要使用存储在 PHP 数组中的数据来编译原始文本。
您可以使用
$str = "and with strange aeons even {{noun}} may {{verb}}";
$data = ['noun' => 'bird', 'verb' => 'fly'];
$pattern = '/{{(' . implode('|', array_keys($data)) . ')}}/i';
echo preg_replace_callback($pattern, function($m) use($data){
return $data[strtolower($m[1])];
}, $str);
// => and with strange aeons even bird may fly
参见PHP demo。
$pattern
看起来像 /{{(noun|verb)}}/i
,并且会在捕获单词本身时匹配双括号内的 noun
或 verb
。替换将是 $data
数组的相应键值。需要使用 strtolower($m[1])
将第 1 组值变为小写,因为 $data
数组中的键都是小写,并且 $pattern
也可以匹配大写变体。
既然你在循环,请保持简单:
foreach ($data as $k => $v) {
$str = str_ireplace('{{'.$k.'}}', $v, $str);
}
如果需要,您可以在 {{
之前和 }}
之后添加 space。
利用 strtr()
收工:
$string = 'and with strange aeons even {{noun}} may {{verb}}';
$data = ['{{noun}}' => 'bird', '{{verb}}' => 'fly'];
echo strtr( $string, $data );
产生:
and with strange aeons even bird may fly
strtr()
很好,因为它不会在以下情况下弄乱字符串:
$data = ['{{noun}}' => 'bi{{verb}}rd', '{{verb}}' => 'fly'];