替换字符串中的占位符变量

Tyl*_*hes 11 php preg-match

刚刚完成这个功能.基本上,假设查看字符串并尝试查找任何占位符变量,这些变量将位于两个大括号之间{}.它抓取大括号之间的值,并使用它来查看应与键匹配的数组.然后它用匹配键数组中的值替换字符串中的大括号变量.

但它有一些问题.首先是当var_dump($matches)它把它放在数组中的数组时.所以我必须使用两个foreach()只是达到正确的数据.

我也觉得它很沉重,我一直在寻找它,试图让它变得更好,但我有点难过.我错过了任何优化?

function dynStr($str,$vars) {
    preg_match_all("/\{[A-Z0-9_]+\}+/", $str, $matches);
    foreach($matches as $match_group) {
        foreach($match_group as $match) {
            $match = str_replace("}", "", $match);
            $match = str_replace("{", "", $match);
            $match = strtolower($match);
            $allowed = array_keys($vars);
            $match_up = strtoupper($match);
            $str = (in_array($match, $allowed)) ? str_replace("{".$match_up."}", $vars[$match], $str) : str_replace("{".$match_up."}", '', $str);
        }
    }
    return $str;
}

$variables = array("first_name"=>"John","last_name"=>"Smith","status"=>"won");
$string = 'Dear {FIRST_NAME} {LAST_NAME}, we wanted to tell you that you {STATUS} the competition.';
echo dynStr($string,$variables);
//Would output: 'Dear John Smith, we wanted to tell you that you won the competition.'
Run Code Online (Sandbox Code Playgroud)

Ham*_*mZa 31

我认为对于这么简单的任务,您不需要使用RegEx:

$variables = array("first_name"=>"John","last_name"=>"Smith","status"=>"won");
$string = 'Dear {FIRST_NAME} {LAST_NAME}, we wanted to tell you that you {STATUS} the competition.';

foreach($variables as $key => $value){
    $string = str_replace('{'.strtoupper($key).'}', $value, $string);
}

echo $string; // Dear John Smith, we wanted to tell you that you won the competition.
Run Code Online (Sandbox Code Playgroud)

  • 这实际上比我的答案更简单,而且可能足够了. (2认同)
  • 哇,是的 我想我们都想得太多了.我会进行一些测试,看看这是否更快,让你知道.足够. (2认同)
  • @HamZaDzCyber​​DeV我太过于痴迷于试图变得"漂亮",以至于像你这样的解决方案并没有浮现在脑海中.有时候先退后一步会有所帮助.但是,对我来说,只有一个小小的警告,虽然你的解决方案是,它不利于从输入字符串中删除无效占位符(但这不是开始的要求). (2认同)
  • 提示:“str_replace”可以采用字符串数组来查找/替换。一次“str_replace”调用可能比一百次调用要快。 (2认同)
  • @DCoder 是的,你是对的,这里的问题是 `$variables` 中的键格式不正确(包含在 {} 和大写字母之间)。 (2认同)

ant*_*ris 14

我希望我加入聚会还不算太晚 - 这就是我要做的事情:

function template_substitution($template, $data) {
    $placeholders = array_keys($data);
    foreach ($placeholders as &$placeholder) {
        $placeholder = strtoupper("{{$placeholder}}");
    }
    return str_replace($placeholders, array_values($data), $template);
}

$variables = array(
    'first_name' => 'John',
    'last_name' => 'Smith',
    'status' => 'won',
);

$string = 'Dear {FIRST_NAME} {LAST_NAME}, we wanted to tell you that you have {STATUS} the competition.';

echo template_substitution($string, $variables);
Run Code Online (Sandbox Code Playgroud)

并且,如果您有可能使您的$variables密钥与您的占位符完全匹配,那么解决方案变得非常简单:

$variables = array(
    '{FIRST_NAME}' => 'John',
    '{LAST_NAME}' => 'Smith',
    '{STATUS}' => 'won',
);

$string = 'Dear {FIRST_NAME} {LAST_NAME}, we wanted to tell you that you have {STATUS} the competition.';

echo strtr($string, $variables);
Run Code Online (Sandbox Code Playgroud)

(参见PHP手册中的strtr().)

考虑到PHP语言的本质,我相信这种方法应该能够从这个线程中列出的所有内容中获得最佳性能.

  • 我同意 - 除了性能之外,这也是最易读和可维护的恕我直言。我对另一个问题 (http://stackoverflow.com/a/36781566/224707) 的回答也显示了这种方法的其他优点,例如在处理之前以编程方式增强替换值的能力(例如编码或主题化它们)...... (2认同)

Dec*_*ler 6

我认为你可以大大简化你的代码(除非我误解了一些要求):

$allowed = array("first_name"=>"John","last_name"=>"Smith","status"=>"won");

$resultString = preg_replace_callback(

    // the pattern, no need to escape curly brackets
    // uses a group (the parentheses) that will be captured in $matches[ 1 ]
    '/{([A-Z0-9_]+)}/',

    // the callback, uses $allowed array of possible variables
    function( $matches ) use ( $allowed )
    {
        $key = strtolower( $matches[ 1 ] );
        // return the complete match (captures in $matches[ 0 ]) if no allowed value is found
        return array_key_exists( $key, $allowed ) ? $allowed[ $key ] : $matches[ 0 ];
    },

    // the input string
    $yourString
);
Run Code Online (Sandbox Code Playgroud)

PS.:如果要删除输入字符串中不允许的占位符,请替换

return array_key_exists( $key, $allowed ) ? $allowed[ $key ] : $matches[ 0 ];
Run Code Online (Sandbox Code Playgroud)

return array_key_exists( $key, $allowed ) ? $allowed[ $key ] : '';
Run Code Online (Sandbox Code Playgroud)

  • @TylerDusty:这是一个[匿名函数](http://php.net/manual/en/functions.anonymous.php),需要PHP 5.3. (3认同)
  • @TylerDusty回调是[闭包](http://www.php.net/manual/en/functions.anonymous.php).`use`结构用于从定义范围导入变量,以便可以在闭包内部使用它.事实上,正如DCoder已经提到的那样,它是一个PHP 5.3+功能. (2认同)