¿Cuándo usar strtr vs str_replace?

86

Me está costando entender cuándo strtrsería preferible str_replaceo viceversa. Parece que es posible lograr exactamente los mismos resultados usando cualquiera de las funciones, aunque el orden en el que se reemplazan las subcadenas se invierte. Por ejemplo:

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');

Esto salidas

YeXY XYring
YeZ Zring
YeXY XYring
YeZ Zring

Aparte de la sintaxis, ¿hay algún beneficio en usar uno sobre el otro? ¿Algún caso en el que uno no sea suficiente para lograr el resultado deseado?

andrewtweber
fuente
3
Desde el punto de vista de la legibilidad, strtrpodría malinterpretarse fácilmente, ya strstrque es bastante diferente. Empiezo a pensar que soy disléxico. No cometeré ese error con str_replace.
Programster

Respuestas:

135

Primera diferencia:

Un ejemplo interesante de un comportamiento diferente entre strtry se str_replaceencuentra en la sección de comentarios del Manual PHP:

<?php
$arrFrom = array("1","2","3","B");
$arrTo = array("A","B","C","D");
$word = "ZBB2";
echo str_replace($arrFrom, $arrTo, $word);
?>
  • Esperaría como resultado: "ZDDB"
  • Sin embargo, este retorno: "ZDDD" (Porque B = D según nuestra matriz)

Para que esto funcione, use "strtr" en su lugar:

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

Esto significa que str_replacees un enfoque más global para los reemplazos, mientras que strtrsimplemente traduce los caracteres uno por uno.


Otra diferencia:

Dado el siguiente código (tomado de Comparación de velocidad de reemplazo de cadenas de 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);
?>

Las líneas de texto resultantes serán:

cadena (3) "PHP"
cadena (27) "PHP: Preprocesador de hipertexto"


La explicación principal:

Esto sucede porque:

  • strtr : ordena sus parámetros por longitud, en orden descendente, así:

    1. le dará "más importancia" al más grande, y luego, como el texto del asunto es en sí mismo la clave más grande de la matriz de reemplazo, se traduce.
    2. debido a que todos los caracteres del texto del tema han sido reemplazados, el proceso termina ahí.
  • str_replace : funciona en el orden en que se definen las claves, entonces:

    1. encuentra la clave "PHP" en el texto del asunto y la reemplaza con: "PHP: Preprocesador de hipertexto", lo que da como resultado:

      “PHP: Preprocesador de hipertexto: Preprocesador de hipertexto”.

    2. luego encuentra la siguiente clave: "PHP: Preprocesador de hipertexto" en el texto resultante del paso anterior, por lo que se reemplaza por "PHP", que da como resultado:

      “PHP: Preprocesador de hipertexto”.

    3. no hay más llaves que buscar, por lo que el reemplazo termina ahí.

Nicolás Ozimica
fuente
2
Ah ok gracias! No me di cuenta de que strtr se traducía por longitud; pensé que era en el orden inverso.
andrewtweber
Como se documenta en php.net, la función str_replace tiene 1 parámetro más llamado "count" para indicar cuántas veces debe realizarse el reemplazo. Pero no puedo usar este parámetro de todos modos. Alguien sabe por qué ?
vantrung -cuncon
1
@ vantrung-cuncon Para eso no es ese parámetro. Los documentos dicen: "Esto se establecerá en el número de reemplazos realizados". Deberá encontrar otra solución si desea limitar str_replace a una cierta cantidad de reemplazos.
jdhartley
1
Limitar el número de reemplazos puede ser útil si desea reemplazar la primera aparición de un acrónimo en la versión extendida, es decir, cambiar la primera aparición de "OMS" por "OMS (Organización Mundial de la Salud)".
Michał Tatarynowicz
strtrno reemplazará el texto insertado por reemplazos anteriores. strtr('foo', array('oo' => 'ie', 'e' => 't'))devuelve en 'fie'lugar de 'fit'como str_replacehace. Por lo tanto, aborda automáticamente el problema planteado por @Pies.
David Harkness
21

Parece que es posible lograr exactamente los mismos resultados usando cualquiera de las funciones

Eso no siempre es cierto y depende de los datos de búsqueda y reemplazo que proporcione. Por ejemplo, si las dos funciones difieren, consulte: ¿PHP str_replace tiene un límite superior a 13 caracteres?

  • strtrno reemplazará en partes de la cadena que ya han sido reemplazadas - str_replacereemplazará el interior reemplaza.
  • strtr comenzará con la clave más larga primero en caso de que la llame con dos parámetros: str_replace se reemplazará de izquierda a derecha.
  • str_replacepuede devolver el número de reemplazos realizados; strtrno ofrece ese valor de recuento.
hakre
fuente
7

Creo que strtrproporciona un reemplazo más flexible y condicional cuando se usa con dos argumentos, por ejemplo: si la cadena es 1, reemplácela con a, pero si la cadena es 10, reemplácela con b. Este truco solo podría lograrse mediante strtr.

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

ver: Php Manual Strtr .

Arif RH
fuente
2

Aviso en el manual STRTR-- Descripción string strtr (string $ str, string $ from, string $ to) string strtr (string $ str, array $ replace_pairs) Si se le dan tres argumentos, esta función devuelve una copia de str donde ...

STR_REPLACE-- ... Si buscar o reemplazar son matrices, sus elementos se procesan del primero al último . ...

STRTR cada turno NO afecta al siguiente, PERO STR_REPLACE lo hace.

Nulo Ninguno
fuente