何时使用strtr和str_replace?

94

我很难理解什么时候会使用strtrstr_replace更好,反之亦然。似乎可以使用任一函数来实现完全相同的结果,尽管替换子字符串的顺序是相反的。例如:

echo strtr('test string', 'st', 'XY')."\n";
echo strtr('test string', array( 's' => 'X', 't' => 'Y', 'st' => 'Z' ))."\n";
echo str_replace(array('s', 't', 'st'), array('X', 'Y', 'Z'), 'test string')."\n";
echo str_replace(array('st', 't', 's'), array('Z', 'Y', 'X'), 'test string');

这将输出:
YeXY XYring
YeZ Zring
YeXY XYring
YeZ Zring

除了语法方面,使用其中一种语言是否有其他好处?有没有某些情况下只能使用其中一种语言才能达到预期的结果?


3
从可读性的角度来看,“strtr”很容易被误读为“strstr”,这两者含义完全不同。我开始认为我有阅读障碍了。使用“str_replace”就不会犯这个错误了。 - Programster
4个回答

151

第一个区别:

strtrstr_replace之间不同行为的有趣示例在PHP手册的评论部分中:

<?php
$arrFrom = array("1","2","3","B");
$arrTo = array("A","B","C","D");
$word = "ZBB2";
echo str_replace($arrFrom, $arrTo, $word);
?>
  • 我希望的结果是:"ZDDB"
  • 然而,实际返回的是:"ZDDD"(因为根据我们的数组,B = D)

要使它起作用,请改用 "strtr":

<?php
$arr = array("1" => "A","2" => "B","3" => "C","B" => "D");
$word = "ZBB2";
echo strtr($word,$arr);
?>
  • 这将返回:"ZDDB"

这意味着str_replace是一种更全局的替换方法,而strtr仅逐个字符地进行翻译。


另一个区别:

给定以下代码(摘自PHP字符串替换速度比较):

<?php
$text = "PHP: Hypertext Preprocessor";

$text_strtr = strtr($text
    , array("PHP" => "PHP: Hypertext Preprocessor"
        , "PHP: Hypertext Preprocessor" => "PHP"));
$text_str_replace = str_replace(array("PHP", "PHP: Hypertext Preprocessor")
    , array("PHP: Hypertext Preprocessor", "PHP")
    , $text);
var_dump($text_strtr);
var_dump($text_str_replace);
?>

最终的文本行如下:

string(3) "PHP"
string(27) "PHP: Hypertext Preprocessor"


主要解释:

这是因为:

  • strtr:它按照长度降序对其参数进行排序,因此:

    1. 它将“更重要”的事物赋予最大的事物,然后,因为主题文本本身是替换数组的最大键,所以它被翻译了。
    2. 因为主题文本的所有字符都已被替换,所以处理到此结束。
  • str_replace:它按照定义的键的顺序工作,因此:

    1. 它在主题文本中找到键“PHP”,并用“PHP: Hypertext Preprocessor”替换它,结果为:
    2. “PHP: Hypertext Preprocessor: Hypertext Preprocessor”。

    3. 然后它在上一步的结果中找到下一个键:“PHP: Hypertext Preprocessor”,所以它被替换为“PHP”,结果为:

      “PHP: Hypertext Preprocessor”。

    4. 没有更多的键需要查找,因此替换到此结束。


2
啊,好的,谢谢!我没意识到 strtr 是按长度进行翻译的 - 我以为它是按相反的顺序。 - andrewtweber
根据php.net文档,函数str_replace有一个名为“count”的额外参数,用于指示替换应执行多少次。但是无论如何我都无法使用这个参数。有人知道为什么吗? - vantrung -cuncon
2
@vantrung-cuncon,那个参数不是用来限定替换次数的。文档中明确指出:“此项将设置为执行的替换次数。”如果您希望将str_replace限制为一定数量的替换,请寻找其他解决方案。 - jdhartley
1
限制替换的次数可能很有用,如果您想将首次出现的缩写替换为扩展版本,即将“WHO”的第一次出现更改为“WHO(世界卫生组织)”。 - Michał Tatarynowicz
1
strtr 不会替换先前替换插入的文本。 strtr('foo',array('oo' => 'ie','e' => 't')) 返回 'fie' 而不是像 str_replace 一样返回 'fit'。 因此,它自动解决了 @Pies 提出的问题。 - David Harkness
值得注意的是,strtr有一个三个参数的模式,其中单个字符直接进行一对一的转换,这不涉及按长度排序... strtr('stack','abcde','12345')会得到'st13k'。 - Gavin Jackson

23

看起来这两个函数可以获得完全相同的结果。

但并非总是如此,这取决于您提供的搜索和替换数据。例如两个函数不同之处,请参见:Does PHP str_replace have a greater than 13 character limit?

  • strtr 不会替换已经被替换的字符串 - str_replace 会在替换内部进行替换。
  • strtr 在使用两个参数时将从最长的键开始替换 - str_replace 将从左到右进行替换。
  • str_replace 可以返回替换完成的数量 - strtr 不提供这样的计数值。

7

我认为strtr在使用两个参数时提供了更加灵活和有条件的替换功能,例如:如果字符串是1,则替换为a,但如果字符串是10,则替换为b。只有通过strtr才能实现这种技巧。

$string = "1.10.0001";  
echo strtr($string, array("1" => "a", "10" => "b"));  
// a.b.000a  

请参考:

查看:Php手册Strtr


2

手册中的注意事项 STRTR-- 描述 string strtr ( string $str , string $from , string $to ) string strtr ( string $str , array $replace_pairs ) 如果给定三个参数,此函数将返回 str 的副本,其中...

STR_REPLACE-- ... 如果搜索或替换是数组,则它们的元素从头到尾进行处理。 ...

STRTR 每次转换不会影响下一次,但 STR_REPLACE 会。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接