Коли використовувати strtr проти str_replace?


86

Мені важко зрозуміти, коли strtrце буде краще str_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

Відповіді:


135

Перша відмінність:

Цікавий приклад різної поведінки між strtrта str_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);
?>

Отримані рядки тексту будуть такими:

рядок (3) рядок "PHP"
(27) "PHP: препроцесор гіпертексту"


Основне пояснення:

Це відбувається тому, що:

  • strtr : він сортує свої параметри за довжиною в порядку зменшення, отже:

    1. це надасть "більше значення" найбільшому, а потім, оскільки текст теми сам є найбільшим ключем масиву заміни, він перекладається.
    2. оскільки всі символи предметного тексту замінені, процес на цьому закінчується.
  • str_replace : він працює в тому порядку, в якому визначені ключі, отже:

    1. він знаходить ключ "PHP" у тексті теми і замінює його на: "PHP: Гіпертекстовий попередник", що дає як результат:

      “PHP: Препроцесор гіпертексту: Препроцесор гіпертексту”.

    2. тоді він знаходить наступний ключ: «PHP: Гіпертекстовий препроцесор» у тексті попереднього кроку, тому він замінюється на «PHP», що дає як результат:

      “PHP: Гіпертекстовий попередник”.

    3. немає більше ключів для пошуку, тому заміна на цьому закінчується.


2
Ах добре дякую! Я не розумів, що strtr перекладає за довжиною - я думав, що це було в зворотному порядку.
— andrewtweber

Як задокументовано в php.net, функція str_replace має ще 1 параметр з назвою "count", щоб вказати, скільки часу повинна виконувати заміна. Але я все одно не можу використовувати цей параметр. Хтось знає чому?
— vantrung -cuncon

1
@ vantrung-cuncon Це не те, для чого призначений цей параметр. У документації сказано: "Для цього буде встановлено кількість виконаних замін." Вам потрібно буде знайти інше рішення, якщо ви хочете обмежити str_replace певною кількістю замін.
— jdhartley

1
Обмеження кількості замін може бути корисним, якщо ви хочете замінити перше входження абревіатури на розширену версію, тобто змінити перше виникнення "WHO" на "WHO (World Health Organization)".
— Міхал Татаринович

strtrне замінить текст, вставлений попередніми замінами. strtr('foo', array('oo' => 'ie', 'e' => 't'))повертається 'fie'замість 'fit'як str_replaceробить. Таким чином, він автоматично вирішує проблему, порушену @Pies.
— Девід Харкнесс,

21

Здається, можливо досягти абсолютно однакових результатів за допомогою будь-якої функції

Це не завжди вірно і залежить від пошуку та заміни даних, які ви надаєте. Наприклад, де дві функції відрізняються, див .: Чи має PHP str_replace більше 13 символів?

  • 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 Manual Strtr .


2

Примітка в ручному STRTR - Опис рядка strtr (рядок $ str, рядок $ від, рядок $ до) рядок strtr (рядок $ str, масив $ replace_pairs) Якщо задано три аргументи, ця функція повертає копію str, де ...

STR_REPLACE-- ... Якщо пошук або заміна є масивами, їх елементи обробляються спочатку до останнього . ...

STRTR кожен поворот НЕ впливає на наступний, АЛЕ STR_REPLACE робить.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.