Когда использовать strtr vs str replace?


бывают случаи, когда трудно понять, когда предпочтительнее использовать strtr и когда использовать str_replace. Кажется, что можно получить тот же результат с любым из них, хотя порядок, в котором substrings заменяются, инвертирован. Например:

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

Помимо синтаксиса, есть ли польза от использования одного или другого? Существуют ли случаи, когда одного было бы недостаточно, чтобы получить результат искали?

оригинальный вопрос: When to use strtr vs str_replace?

Author: Comunidad, 2015-12-01

2 answers

Примечание к переводу: оригинальный вопрос был поднят @andrewtweber и ответил сам на сайте StackOverflow на английском языке.

Первое отличие:

Интересный пример дифференцированного поведения между 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" (Потому что А Б это соответствует D в соответствии с нашей договоренностью)

Чтобы заставить это работать так, как можно было бы ожидать, лучше использовать strtr:

<?php
$arr = array("1" => "A","2" => "B","3" => "C","B" => "D");
$word = "ZBB2";
echo strtr($word,$arr);
?>
  • что возвращает: "ZDDB"

Это означает, что str_replace использует более глобальный подход к заменам, в то время как strtr просто переводит символы один за другим.


Еще одно отличие:

Учитывая следующий код: (взято из 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);
?>

Результирующими строками текста будут:

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


Основное объяснение:

Причины такого поведения:

  • Strtr: сортирует ваши параметры по длине, в порядке убывания, поэтому:

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

    1. находит ключ "PHP" в основном тексте и заменяет его на: "PHP: Hypertext Preprocessor", что приводит к:

      " PHP: Hypertext Preprocessor: Hypertext Preprocessor".

    2. затем найдите следующий ключ: "PHP: Hypertext Preprocessor" в результирующем тексте предыдущего шага, поэтому он заменяется "PHP", что приводит к:

      "PHP: Hypertext Preprocessor".

    3. поскольку больше нет ключей для проверки, процесс замены заканчивается на этом.
 9
Author: Nicolás, 2017-05-23 12:39:20

Дополняя объяснение Николая, результат различается поведением функций.

  • strtr предназначен для замены символов, независимо от того, какую форму вы используете, и перебирает основную строку символ за символом, когда находит совпадение с символами поиска, заменяет его и переходит к следующему символу.
  • str_replace предназначен для замены подстроек, независимо от длины источника и судьба, в отличие от предыдущих, которые должны быть отдельными символами. Таким образом, для каждого элемента, подлежащего поиску, он проходит через всю основную строку, заменяет все совпадения в ней, а затем переходит к следующей подстроке ... если вы перейдете к примеру Николаса, "2" заменяется повсюду на "B", а в другом последующем поиске изменяется "B" на "D", и, будучи отдельными обходами, мы получаем "ZDDD" вместо"ZDDB".

В дополнение к этому, время отклика, не это будет очень заметно с небольшими строками, но чем больше длина, тем больше времени потребуется str_replace.

Предположим, что у нас есть основная строка из 100 символов, и давайте перейдем к поиску 10 символов:

  • с str_replace каждый символ будет искать в топ-100, что даст в общей сложности тысячу поисков.
  • С strtr при совпадении остальная часть поиска по этому символу игнорируется, заканчиваясь менее чем на 10 поиск, и каждое совпадение сделает поиск незначительным.

Таким образом, если есть совпадения с strtr будет выполняться меньше тысячи поисков, тогда как с str_replace всегда будет выполняться тысяча поисков, независимо от того, есть ли совпадения или нет.

 5
Author: Willem Franco, 2015-12-17 01:21:45