使用正则表达式在 php 中执行精简版模板的最佳方式

Best way to perform lite templating in php with regular expression

您好,我正在尝试在 PHP 中执行一个非常简单的模板系统。

我想这样做:

目前我已经这样做了(不是在正则表达式中而且它不起作用)

class Markdown{
    private static $folder = 'markdowns/';

    public static function fill_template($template, $array){

        $text = file_get_contents(self::$folder . $template . '.md'); 
        foreach($array as $key => $value){
            $text = str_replace('{{'.$key.'}}', $value, $text);
        }

        return $text;
    }
}

有什么想法吗?

谢谢

您可以使用 preg_replace_callback 来获得简单的渲染器

function render($template, $vars) {
    return \preg_replace_callback("!{{\s*(?P<key>[a-zA-Z0-9_-]+?)\s*}}!", function($match) use($vars){
        return isset($vars[$match["key"]]) ? $vars[$match["key"]] : $match[0];
    }, $template);
}

示例

echo render(
    "Hello {{ name  }}, how are you today? Date: {{time   }} and it's {{weather}} in {{location}}\n", 
    ["name"=>"World!!", "time"=>date("c")]
);

将渲染到

Hello World!!, how are you today? Date: 2018-04-05T06:40:34+00:00 and it's {{weather}} in {{location}}

您可以使用 preg_replace_callback() 将模式 {{variable}} 转换为其对应的值:

public static function fill_template($template, $array){
    $text = file_get_contents(self::$folder . $template . '.md');
    $text = preg_replace_callback('~\{\{([^}]+)\}\}~', function($matches) use ($array) {
        $key = trim($matches[1]); // remove unwanted spaces
        if (isset($array[$key])) return $array[$key]; // return the value if found
        // If not found, return the key:
        return $key;
    }, $text);
    return $text;
}

如果在数组中没有找到匹配项,返回内容时不带{{}}

正则表达式:

~       # delimiter
\{\{    # two literal { - need to be escaped
(       # start capture group
 [^}]+  # all character until }
)       # end capture group
\}\}    # two literal } - need to be escaped
~       # end delimiter