Kiedy używać strtr vs str_replace?

86

Trudno mi zrozumieć, kiedy strtrbyłoby lepsze str_replacelub odwrotnie. Wydaje się, że możliwe jest osiągnięcie dokładnie tych samych wyników przy użyciu obu funkcji, chociaż kolejność, w której zastępowane są podciągi, jest odwrotna. Na przykład:

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

To wychodzi

YeXY XYring
YeZ Zring
YeXY XYring
YeZ Zring

Oprócz składni, czy jest jakaś korzyść z używania jednego nad drugim? Czy są przypadki, w których nie wystarczyłoby do osiągnięcia pożądanego rezultatu?

andrewtweber
źródło
3
Z punktu widzenia czytelności strtrmoże być łatwo odczytany, ponieważ strstrjest zupełnie inny. Zaczynam myśleć, że mam dysleksję. Nie popełnię tego błędu z str_replace.
Programster

Odpowiedzi:

135

Pierwsza różnica:

Ciekawy przykład innego zachowania między strtri str_replaceznajduje się w sekcji komentarzy podręcznika PHP:

<?php
$arrFrom = array("1","2","3","B");
$arrTo = array("A","B","C","D");
$word = "ZBB2";
echo str_replace($arrFrom, $arrTo, $word);
?>
  • Spodziewałbym się wyniku: „ZDDB”
  • Jednak ten zwrot: „ZDDD” (Ponieważ B = D zgodnie z naszą tablicą)

Aby to zadziałało, użyj zamiast tego „strtr”:

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

Oznacza to, że str_replacejest to bardziej globalne podejście do zastępowania, podczas gdy strtrpo prostu tłumaczy znaki jeden po drugim.


Kolejna różnica:

Biorąc pod uwagę następujący kod (wzięty z porównania szybkości zastępowania ciągów 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);
?>

Wynikowe wiersze tekstu będą wyglądać następująco:

string (3) "PHP"
string (27) "PHP: preprocesor hipertekstu"


Główne wyjaśnienie:

Dzieje się tak, ponieważ:

  • strtr : sortuje swoje parametry według długości, w porządku malejącym, więc:

    1. nada „większe znaczenie” największemu, a następnie, ponieważ tekst tematu jest sam w sobie największym kluczem tablicy zastępczej, zostanie przetłumaczony.
    2. ponieważ wszystkie znaki tekstu tematu zostały zastąpione, proces kończy się na tym.
  • str_replace : działa w kolejności, w jakiej klucze są zdefiniowane, więc:

    1. znajduje klucz „PHP” w tekście tematu i zastępuje go: „PHP: Hypertext Preprocessor”, co daje w rezultacie:

      „PHP: Hypertext Preprocessor: Hypertext Preprocessor”.

    2. następnie znajduje następny klucz: „PHP: Hypertext Preprocessor” w wynikowym tekście poprzedniego kroku, więc jest zastępowany przez „PHP”, co daje w rezultacie:

      „PHP: Hypertext Preprocessor”.

    3. nie ma już kluczy do poszukiwania, więc wymiana kończy się na tym.

Nicolás Ozimica
źródło
2
Ach ok dzięki! Nie zdawałem sobie sprawy, że strtr tłumaczy według długości - myślałem, że to w odwrotnej kolejności.
andrewtweber
Jak udokumentowano w php.net, funkcja str_replace ma jeszcze 1 paramerter o nazwie „count”, aby wskazać, ile razy ma wykonać zamiana. Ale i tak nie mogę użyć tego parametru. Czy ktoś wie dlaczego?
vantrung -cuncon
1
@ vantrung-cuncon Nie do tego służy ten parametr. Dokumenty mówią: „Będzie to ustawione na liczbę wykonanych wymian”. Będziesz musiał znaleźć inne rozwiązanie, jeśli chcesz ograniczyć str_replace do określonej liczby wymian.
jdhartley
1
Ograniczenie liczby zastąpień może być przydatne, jeśli chcesz zamienić pierwsze wystąpienie akronimu na wersję rozszerzoną, tj. Zmienić pierwsze wystąpienie „WHO” na „WHO (Światowa Organizacja Zdrowia)”.
Michał Tatarynowicz
strtrnie zastąpi tekstu wstawionego przez poprzednie zamiany. strtr('foo', array('oo' => 'ie', 'e' => 't'))zwraca 'fie'zamiast 'fit'jak str_replacerobi. W ten sposób automatycznie rozwiązuje problem podniesiony przez @Pies.
David Harkness,
21

Wydaje się, że możliwe jest osiągnięcie dokładnie tych samych wyników przy użyciu obu funkcji

Nie zawsze jest to prawdą i zależy od podanych przez Ciebie danych wyszukiwania i zamiany. Na przykład, gdy te dwie funkcje się różnią, zobacz: Czy PHP str_replace ma więcej niż 13 znaków?

  • strtr nie zastąpi w częściach ciągu, które zostały już zastąpione - str_replace zamieni wewnątrz zastępuje.
  • strtr rozpocznie się od najdłuższego klucza w przypadku wywołania go z dwoma parametrami - str_replace zostanie zastąpiony od lewej do prawej.
  • str_replacemoże zwrócić liczbę wykonanych wymian - strtrnie podaje takiej wartości licznika.
hakre
źródło
7

Myślę, że strtrzapewnia bardziej elastyczne i warunkowe zastępowanie, gdy jest używane z dwoma argumentami, na przykład: jeśli ciąg wynosi 1, zamień na a, ale jeśli ciąg ma wartość 10, zamień na b. Tę sztuczkę można było osiągnąć tylko przez strtr.

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

zobacz: Podręcznik Php Strtr .

Arif RH
źródło
2

Uwaga w instrukcji STRTR - Opis string strtr (string $ str, string $ from, string $ to) string strtr (string $ str, tablica $ replace_pairs) Jeśli podano trzy argumenty, funkcja zwraca kopię gdzie ...

STR_REPLACE-- ... Jeśli wyszukiwanie lub zamiana są tablicami, ich elementy są przetwarzane od pierwszego do ostatniego . ...

STRTR w każdej turze NIE ma wpływu na następną, ALE STR_REPLACE tak.

Brak Brak
źródło