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?


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.


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.

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 .


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.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.