เมื่อใดควรใช้ strtr vs str_replace


87

ฉันมีปัญหาในการทำความเข้าใจว่าเมื่อ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

คำตอบ:


136

ความแตกต่างประการแรก:

ตัวอย่างที่น่าสนใจของพฤติกรรมที่แตกต่างระหว่าง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 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" (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: ตัวประมวลผลไฮเปอร์เท็กซ์”

    3. ไม่มีคีย์ให้ค้นหาอีกต่อไปดังนั้นการเปลี่ยนจึงสิ้นสุดที่นั่น


2
โอเคขอบคุณ! ฉันไม่รู้ว่า strtr แปลตามความยาว - ฉันคิดว่ามันอยู่ในลำดับย้อนกลับ
andrewtweber

ตามที่ระบุไว้ใน php.net ฟังก์ชัน str_replace มีพารามิเตอร์อีก 1 ตัวที่ชื่อ "count" เพื่อระบุว่าควรเปลี่ยนกี่ครั้ง แต่ฉันไม่สามารถใช้พารามิเตอร์นี้ได้อยู่ดี มีใครรู้บ้างว่าทำไม?
vantrung -cuncon

2
@ vantrung-cuncon นั่นไม่ใช่สิ่งที่พารามิเตอร์นั้นมีไว้สำหรับ เอกสารกล่าวว่า: "สิ่งนี้จะถูกกำหนดเป็นจำนวนการเปลี่ยนทดแทน" คุณจะต้องหาวิธีแก้ปัญหาอื่นหากคุณต้องการ จำกัด str_replace ไว้ที่การแทนที่จำนวนหนึ่ง
jdhartley

1
การ จำกัด จำนวนการแทนที่อาจมีประโยชน์หากคุณต้องการแทนที่ตัวย่อที่เกิดขึ้นครั้งแรกเป็นเวอร์ชันขยายนั่นคือเปลี่ยนการเกิดขึ้นครั้งแรกของ "WHO" เป็น "WHO (องค์การอนามัยโลก)"
Michał Tatarynowicz

1
strtrจะไม่แทนที่ข้อความที่แทรกโดยการแทนที่ก่อนหน้านี้ strtr('foo', array('oo' => 'ie', 'e' => 't'))ผลตอบแทน'fie'แทนที่จะ'fit'เป็นเช่นstr_replaceนั้น ดังนั้นจึงจัดการปัญหาที่เกิดขึ้นโดย @Pies โดยอัตโนมัติ
David Harkness

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 คู่มือ Strtr


2

ข้อสังเกตใน STRTR ด้วยตนเอง - คำอธิบาย string strtr (string $ str, string $ from, string $ to) string strtr (string $ str, array $ replace_pairs) หากได้รับสามอาร์กิวเมนต์ฟังก์ชันนี้จะส่งคืนสำเนาของ str โดยที่ ...

STR_REPLACE-- ... หากการค้นหาหรือเปลี่ยนเป็นอาร์เรย์องค์ประกอบของพวกเขามีการประมวลผลครั้งแรกที่ผ่านมา ...

STRTR ในแต่ละเทิร์นจะไม่มีผลต่อไป แต่ STR_REPLACE ทำ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.