【问题标题】:Making a simple templating engine in PHP用 PHP 制作一个简单的模板引擎
【发布时间】:2021-03-13 18:42:24
【问题描述】:

我需要编写一个简单的 PHP 函数来用它们各自的数据替换 {{ }} 字符之间的文本。

示例:

String: "甚至还有奇怪的永恒 {{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}}

如何调整正则表达式和/或代码以解决双花括号?

另外,在有人问我为什么要手动执行此操作而不是使用 PHP 本身或 Smarty 插件之前——安装插件的用例太窄,我不能使用 PHP 本身,因为输入字符串以来自数据库的原始文本形式出现。我需要使用存储在 PHP 数组中的数据来编译该原始文本。

【问题讨论】:

    标签: php regex templating preg-replace-callback templating-engine


    【解决方案1】:

    你可以使用

    $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,并且在捕获单词本身时将匹配双括号内的nounverb。替换将是$data 数组的对应键值。需要使用 strtolower($m[1]) 将 Group 1 值转换为小写,因为 $data 数组中的键都是小写的,$pattern 也可以匹配大写变体。

    【讨论】:

    • 聪明的解决方案。最重要的是,它奏效了!谢谢
    • 如果键包含特殊字符,我建议使用array_map()preg_quote() 应用于array_keys($data)
    • 如果值包含$1 或其他内容,则可能需要对赋予preg_replace_callback() 的值执行类似的操作。
    • @MonkeyZeus 如果有必要,我将在答案中添加implode("|", array_map(function($i) { return preg_quote(trim($i), "/"); }, array_keys($data))) 而不是implode('|', array_keys($data))。我怀疑nounverb,任何POS值都不止一个字母。
    • 我真的无法预测 OP 的未来计划,但最好提前强化代码而不是尝试调试未来的问题,特别是如果 OP 不是将来维护代码的人。
    【解决方案2】:

    既然你在循环,那就保持简单:

    foreach ($data as $k => $v) {
        $str = str_ireplace('{{'.$k.'}}', $v, $str);
    }
    

    如果需要,您可以在{{ 之前和}} 之后添加一个空格。

    【讨论】:

      【解决方案3】:

      使用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'];
      

      【讨论】:

      • strstr 是一个很好的解决方案,如果您可以控制数组键并将'{{ }} 添加到它们。
      猜你喜欢
      • 1970-01-01
      • 2011-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多