【问题标题】:Replacing tokens in a string from an array从数组中替换字符串中的标记
【发布时间】:2009-10-25 11:15:05
【问题描述】:

假设我有一个字符串

这个 $0 是 $2 $1。不过,对于一只小狗来说,\$$3 还是很多的。

还有一个替换数组

array('puppy', 'cute', 'ridiculously', '1300')

用数组中的相应项替换字符串中的标记,让我用反斜杠转义标记字符(在本例中为$),最干净的方法是什么?我还想用空字符串替换不匹配的标记。

【问题讨论】:

    标签: php


    【解决方案1】:
    foreach ($array AS $key => $value)
    {
        $string = str_replace('$' . $key, $value, $string);
    }
    

    【讨论】:

    • 谢谢。这是一个不错且简单的解决方案,但它不能处理两种情况:转义字符串中的文字 $s 和不匹配的标记(将它们留在字符串中是有效的,但我宁愿删除它们)。我将更新问题以澄清。
    • 不尊重反斜杠转义
    • 感谢投反对票的人。 FWIW,最初的问题(我正在回答的问题)没有提到反斜杠转义。
    【解决方案2】:

    我猜你的意思是“\$3”,而不是“\$$3”

    preg_replace('~(?<!\\\\)\$(\d+)~e', 'isset($array[$1])?$array[$1]:""', $source);
    

    顺便说一句,您知道 sprintf 也允许编号参数(http://php.net/manual/en/function.sprintf.php 示例 3)

    【讨论】:

    • 我将 \$$3 解释为转义 $,然后将 $3 变量读取为 $1300。我不认为这是一个错字。
    • cletus 的回答是最完整的,但我无法与单行者争论。需要使用第二个 preg_replace 快速通过以从转义的 $ 中删除反斜杠。
    【解决方案3】:
    $test_sub= 'This $0 is $2 $1. Still, \$$3 is a lot to pay for a puppy.';
    $GLOBALS['replacers'] = array('puppy', 'cute', 'ridiculously', '1300');
    echo preg_replace_callback('/[^\$]\$([0-9])+/',
        create_function(
            '$matches',
            'return $matches[0][0] . $GLOBALS[\'replacers\'][$matches[1]];'
        ),
        $test_sub
    );
    

    这是如何完成的 POC。一个简单的正则表达式和一个用于替换的回调。实际的实现取决于你想要用它做什么。我希望它有所帮助。

    【讨论】:

      【解决方案4】:

      这是一个版本。

      $replacements = array('puppy', 'cute', 'ridiculously', '1300');
      $input = 'This $0 is $2 $1. Still, \$3 is a lot to pay for a puppy.';
      
      $output = preg_replace_callback('/(?<!\\\\)\$(\d+)/', 'replace_input', $input);
      
      echo $input . "<br>";
      echo $output;
      
      function replace_input($matches) {
        global $replacements;
        $index = $matches[1];
        return $index < 0 || $index >= count($replacements) ? $matches[0] : $replacements[$index];
      }
      

      输出:

      This $0 is $2 $1. Still, \$3 is a lot to pay for a puppy.
      This puppy is ridiculously cute. Still, \$3 is a lot to pay for a puppy.
      

      它在 $ 之前处理反斜杠以转义该变量。这可能是一种尴尬的语法,因为您需要转义反斜杠,这会使它进一步复杂化(在这种情况下不处理)。正则表达式基本上意味着 $ 后跟一个或多个数字,只要 $ 前面没有反斜杠(使用 negative lookbehind)。

      它使用全局替换数组。有两种选择:

      1. 使用闭包(需要 PHP 5.3+);或
      2. 使用create_function()

      但我认为全局更简单和“全局”,除非你有充分的理由去做一些不同的事情,尽管我们通常不喜欢这些事情。

      【讨论】:

        【解决方案5】:

        此解决方案遵循问题并借鉴了 Josh Leitzel 的回答。不匹配的模式(例如 $4、$5)被空字符串替换,从输入中删除。

        $input = "This $0 is $2 $1. Still, \$$3 is a lot to pay for a puppy.";
        $replacements = array('puppy','cute','ridiculously','1300');
        $pattern = "/[$]{1}([0-9]{1})/";
        
        preg_match_all($pattern, $input, $matches);
        
        if (isset($matches[1]))
         foreach ($matches[1] as $key => $value)
         {
          $input = str_replace("$".$value, $replacements[$value], $input);
         }
        
        echo $input;
        

        输出:

        这只小狗非常可爱。尽管如此,1300 美元对于一只小狗来说仍然是一笔不小的数目。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-12-15
          • 1970-01-01
          • 2010-10-31
          • 1970-01-01
          • 2010-09-28
          • 2012-04-26
          • 2011-07-16
          • 2016-02-04
          相关资源
          最近更新 更多