Quando usare strtr vs str_replace?


87

Faccio fatica a capire quando strtrsarebbe preferibile str_replaceo viceversa. Sembra che sia possibile ottenere esattamente gli stessi risultati utilizzando entrambe le funzioni, sebbene l'ordine in cui vengono sostituite le sottostringhe sia invertito. Per esempio:

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

Questo produce

YeXY XYring
YeZ Zring
YeXY XYring
YeZ Zring

A parte la sintassi, c'è qualche vantaggio nell'usare l'uno sull'altro? Eventuali casi in cui uno non sarebbe sufficiente per ottenere un risultato desiderato?


3
Dal punto di vista della leggibilità, strtrpotrebbe essere facilmente interpretato male in quanto strstrè molto diverso. Comincio a pensare di essere dislessico. Non commetterò questo errore con str_replace.
Programster

Risposte:


136

Prima differenza:

Un esempio interessante di un comportamento diverso tra strtre si str_replacetrova nella sezione commenti del manuale PHP:

<?php
$arrFrom = array("1","2","3","B");
$arrTo = array("A","B","C","D");
$word = "ZBB2";
echo str_replace($arrFrom, $arrTo, $word);
?>
  • Mi aspetto come risultato: "ZDDB"
  • Tuttavia, questo ritorno: "ZDDD" (perché B = D secondo il nostro array)

Per farlo funzionare, usa invece "strtr":

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

Ciò significa che str_replaceè un approccio più globale alle sostituzioni, mentre strtrtraduce semplicemente i caratteri uno per uno.


Un'altra differenza:

Dato il seguente codice (tratto da PHP String Replacement Speed ​​Comparison ):

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

Le righe di testo risultanti saranno:

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


La spiegazione principale:

Questo accade perché:

  • strtr : ordina i suoi parametri in base alla lunghezza, in ordine decrescente, quindi:

    1. darà "più importanza" a quello più grande e poi, poiché il testo dell'oggetto è esso stesso la chiave più grande dell'array di sostituzione, verrà tradotto.
    2. poiché tutti i caratteri del testo dell'oggetto sono stati sostituiti, il processo finisce qui.
  • str_replace : funziona nell'ordine in cui sono definite le chiavi, quindi:

    1. trova la chiave "PHP" nel testo dell'oggetto e la sostituisce con: "PHP: Hypertext Preprocessor", cosa dà come risultato:

      "PHP: Hypertext Preprocessor: Hypertext Preprocessor".

    2. quindi trova la chiave successiva: "PHP: Hypertext Preprocessor" nel testo risultante del passaggio precedente, quindi viene sostituito da "PHP", che dà come risultato:

      "PHP: Hypertext Preprocessor".

    3. non ci sono più chiavi da cercare, quindi la sostituzione finisce qui.


2
Ah ok grazie! Non mi rendevo conto che strtr stava traducendo in base alla lunghezza, pensavo fosse nell'ordine inverso.
andrewtweber

Come documentato in php.net, la funzione str_replace ha un ulteriore parametro chiamato "count" per indicare quante volte deve essere eseguita la sostituzione. Ma non sono comunque in grado di utilizzare questo parametro. Qualcuno sa perché?
vantrung -cuncon

2
@ vantrung-cuncon Non è a questo che serve quel parametro. I documenti dicono: "Questo sarà impostato sul numero di sostituzioni eseguite". Sarà necessario trovare un'altra soluzione se si desidera limitare str_replace a una certa quantità di sostituzioni.
jdhartley

1
Limitare il numero di sostituzioni può essere utile se si desidera sostituire la prima occorrenza di un acronimo nella versione estesa, ovvero modificare la prima occorrenza di "WHO" in "WHO (World Health Organization)".
Michał Tatarynowicz

1
strtrnon sostituirà il testo inserito da precedenti sostituzioni. strtr('foo', array('oo' => 'ie', 'e' => 't'))restituisce 'fie'invece di 'fit'come str_replacefa. Quindi risolve automaticamente il problema sollevato da @Pies.
David Harkness,

21

Sembra che sia possibile ottenere esattamente gli stessi risultati utilizzando entrambe le funzioni

Non è sempre vero e dipende dalla ricerca e dalla sostituzione dei dati forniti. Ad esempio, se le due funzioni differiscono, vedere: PHP str_replace ha un limite superiore a 13 caratteri?

  • strtrnon sostituirà le parti della stringa che sono già state sostituite - str_replacesostituirà le sostituzioni interne.
  • strtrinizierà con il tasto più lungo per primo nel caso in cui lo chiami con due parametri - str_replacesostituirà da sinistra a destra.
  • str_replacepuò restituire il numero di sostituzioni effettuate - strtrnon offre tale valore di conteggio.

7

Penso che strtrfornisca una sostituzione più flessibile e condizionale quando viene utilizzato con due argomenti, ad esempio: se stringa è 1, sostituisci con a, ma se stringa è 10, sostituisci con b. Questo trucco può essere ottenuto solo da strtr.

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

vedi: Php Manual Strtr .


2

Avviso nel manuale STRTR-- Descrizione stringa strtr (stringa $ str, stringa $ da, stringa $ a) stringa strtr (stringa $ str, array $ replace_pairs) Se vengono forniti tre argomenti, questa funzione restituisce una copia di str dove ...

STR_REPLACE-- ... Se la ricerca o la sostituzione sono array, i loro elementi vengono elaborati dal primo all'ultimo . ...

STRTR ogni turno NON ha effetto su quello successivo, MA STR_REPLACE lo fa.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.