Khi nào sử dụng strtr so với str_replace?


86

Tôi đang rất khó hiểu khi nào strtrsẽ thích hợp hơn str_replacehoặc ngược lại. Có vẻ như có thể đạt được kết quả giống hệt nhau bằng cách sử dụng một trong hai hàm, mặc dù thứ tự các chuỗi con được thay thế bị đảo ngược. Ví dụ:

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

Kết quả này

YeXY XYring
YeZ Zring
YeXY XYring
YeZ Zring

Ngoài cú pháp, có lợi ích gì khi sử dụng cái này so với cái kia không? Bất kỳ trường hợp nào không đủ để đạt được kết quả mong muốn?


3
Từ quan điểm dễ đọc, strtrcó thể dễ dàng bị đọc nhầm vì strstrnó khá khác biệt. Tôi bắt đầu nghĩ rằng tôi mắc chứng khó đọc. Sẽ không mắc lỗi đó với str_replace.
trình

Câu trả lời:


135

Điểm khác biệt đầu tiên:

Một ví dụ thú vị về một hành vi khác nhau giữa strtrstr_replacenằm trong phần nhận xét của Hướng dẫn sử dụng PHP:

<?php
$arrFrom = array("1","2","3","B");
$arrTo = array("A","B","C","D");
$word = "ZBB2";
echo str_replace($arrFrom, $arrTo, $word);
?>
  • Tôi mong đợi kết quả là: "ZDDB"
  • Tuy nhiên, trả về này: "ZDDD" (Vì B = D theo mảng của chúng ta)

Để làm cho việc này hoạt động, hãy sử dụng "strtr" thay thế:

<?php
$arr = array("1" => "A","2" => "B","3" => "C","B" => "D");
$word = "ZBB2";
echo strtr($word,$arr);
?>
  • Điều này trả về: "ZDDB"

Điều này có nghĩa là đó str_replacelà một cách tiếp cận toàn cầu hơn để thay thế, trong khi strtrchỉ cần dịch từng ký tự một.


Một sự khác biệt khác:

Cho đoạn mã sau (lấy từ So sánh tốc độ thay thế chuỗi 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);
?>

Các dòng văn bản kết quả sẽ là:

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


Lời giải thích chính:

Điều này xảy ra bởi vì:

  • strtr : nó sắp xếp các tham số của nó theo độ dài, theo thứ tự giảm dần, vì vậy:

    1. nó sẽ cung cấp "tầm quan trọng hơn" cho cái lớn nhất, và sau đó, vì bản thân văn bản chủ đề là khóa lớn nhất của mảng thay thế, nó sẽ được dịch.
    2. bởi vì tất cả các ký tự của văn bản chủ đề đã được thay thế, quá trình kết thúc ở đó.
  • str_replace : nó hoạt động theo thứ tự các khóa được xác định, vì vậy:

    1. nó tìm thấy khóa “PHP” trong văn bản chủ đề và thay thế nó bằng: “PHP: Hypertext Preprocessor”, kết quả là:

      “PHP: Hypertext Preprocessor: Bộ tiền xử lý siêu văn bản”.

    2. sau đó nó tìm thấy khóa tiếp theo: “PHP: Hypertext Preprocessor” trong văn bản kết quả của bước trước đó, vì vậy nó được thay thế bằng "PHP", kết quả là:

      “PHP: Bộ tiền xử lý siêu văn bản”.

    3. không còn chìa khóa để tìm kiếm nữa, vì vậy việc thay thế kết thúc ở đó.


2
Ah ok, cảm ơn! Tôi không nhận ra rằng strtr đang dịch theo độ dài - tôi nghĩ rằng nó theo thứ tự ngược lại.
andrewtweber

Theo tài liệu trong php.net, hàm str_replace có thêm 1 paramerter có tên "count" để cho biết thời gian thực hiện thay thế. Nhưng tôi không thể sử dụng tham số này. Có ai biết tại sao không ?
vantrung -cuncon

1
@ vantrung-cuncon Đó không phải là tham số đó. Tài liệu cho biết: "Điều này sẽ được đặt thành số lần thay thế được thực hiện." Bạn sẽ cần phải tìm một giải pháp khác nếu bạn muốn giới hạn str_replace ở một số lượng thay thế nhất định.
jdhartley

1
Giới hạn số lần thay thế có thể hữu ích nếu bạn muốn thay thế lần xuất hiện đầu tiên của một từ viết tắt thành phiên bản mở rộng, tức là thay đổi lần xuất hiện đầu tiên của "WHO" thành "WHO (Tổ chức Y tế Thế giới)".
Michał Tatarynowicz,

strtrsẽ không thay thế văn bản được chèn bởi các thay thế trước đó. strtr('foo', array('oo' => 'ie', 'e' => 't'))trả về 'fie'thay vì 'fit'như str_replacekhông. Do đó, nó tự động giải quyết vấn đề do @Pies đưa ra.
David Harkness

21

Có vẻ như có thể đạt được kết quả giống hệt nhau bằng cách sử dụng một trong hai chức năng

Điều đó không phải lúc nào cũng đúng và phụ thuộc vào dữ liệu tìm kiếm và thay thế bạn cung cấp. Ví dụ, khi hai hàm khác nhau, hãy xem: PHP str_replace có giới hạn ký tự lớn hơn 13 không?

  • strtrsẽ không thay thế trong các phần của chuỗi đã được thay thế - str_replacesẽ thay thế bên trong thay thế.
  • strtrsẽ bắt đầu với phím dài nhất trước trong trường hợp bạn gọi nó với hai tham số - str_replacesẽ thay thế từ trái sang phải.
  • str_replacecó thể trả về số lần thay thế được thực hiện - strtrkhông cung cấp giá trị đếm như vậy.

7

Tôi nghĩ strtrcung cấp sự thay thế có điều kiện và linh hoạt hơn khi được sử dụng với hai đối số, ví dụ: nếu chuỗi là 1, hãy thay thế bằng a, nhưng nếu chuỗi là 10, hãy thay thế bằng b. Thủ thuật này chỉ có thể đạt được bằng strtr.

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

xem: Php Manual Strtr .


2

Lưu ý trong STRTR thủ công - Chuỗi mô tả strtr (chuỗi $ str, chuỗi $ từ, chuỗi $ đến) chuỗi strtr (chuỗi $ str, mảng $ Replace_pairs) Nếu cho ba đối số, hàm này trả về một bản sao của str trong đó ...

STR_REPLACE-- ... Nếu tìm kiếm hoặc thay thế là mảng, các phần tử của chúng sẽ được xử lý trước đến cuối . ...

STRTR mỗi lượt KHÔNG ảnh hưởng đến lượt tiếp theo, NHƯNG STR_REPLACE thì không.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.