Коли використовувати 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.