note 88569 added to function.str-replace

From: Date: Thu, 29 Jan 2009 14:38:46 +0000
Subject: note 88569 added to function.str-replace
Groups: php.notes 
Request: Send a blank email to php-notes+get-149944@lists.php.net to get a copy of this message
As previous commentators mentioned, when $search contains values that occur earlier in $replace, str_replace will factor those previous replacements into the process rather than operating solely on the original string. This may produce unexpected output. Example: <?php $search = array('A', 'B', 'C', 'D', 'E'); $replace = array('B', 'C', 'D', 'E', 'F'); $subject = 'ABCDE'; echo str_replace($search, $replace, $subject); // output: 'FFFFFF' ?> In the above code, the $search and $replace should replace each occurrence in the $subject with the next letter in the alphabet. The expected output for this sample is 'BCDEF'; however, the actual output is 'FFFFF'. To more clearly illustrate this, consider the following example: <?php $search = array('A', 'B', 'C', 'D', 'E'); $replace = array('B', 'C', 'D', 'E', 'F'); $subject = 'A'; echo str_replace($search, $replace, $subject); // output: 'F' ?> Since 'A' is the only letter in the $search array that appears in $subject, one would expect the result to be 'B'; however, replacement number $n does *not* operate on $subject, it operates on $subject after the previous $n-1 replacements have been completed. The following function utilizes array_combine and strtr to produce the expected output, and I believe it is the most efficient way to perform the desired string replacement without prior replacements affecting the final result. <?php /** * When using str_replace(...), values that did not exist in the original string (but were put there by previous * replacements) will be replaced continuously. This string replacement function is designed replace the values * in $search with those in $replace while not factoring in prior replacements. Note that this function will * always look for the longest possible match first and then work its way down to individual characters. * * The "o" in "stro_replace" represents "original", indicating that the function operates only on the original string. * * @param array $search list of strings or characters that need to be replaced * @param array $replace list of strings or characters that will replace the corresponding values in $search * @param string $subject the string on which this operation is being performed * * @return string $subject with all substrings in the $search array replaced by the values in the $replace array */ function stro_replace($search, $replace, $subject) { return strtr( $subject, array_combine($search, $replace) ); } $search = array('A', 'B', 'C', 'D', 'E'); $replace = array('B', 'C', 'D', 'E', 'F'); $subject = 'ABCDE'; echo stro_replace($search, $replace, $subject); // output: 'BCDEF' ?> Some other examples: <?php $search = array(' ', '&'); $replace = array('&nbsp;', '&amp;'); $subject = 'Hello & goodbye!'; // We want to replace the spaces with &nbsp; and the ampersand with &amp; echo str_replace($search, $replace, $subject); // output: "Hello&amp;nbsp&amp;&amp;nbspgoodbye!" - wrong! echo stro_replace($search, $replace, $subject); // output: "Hello&nbsp;&amp;&nbsp;goodbye!" - correct! /* Note: Run the above code in the CLI or view source on your web browser - the replacement strings for stro_replace are HTML entities which the browser interprets. */ ?> <?php $search = array('ERICA', 'AMERICA'); $replace = array('JON', 'PHP'); $subject = 'MIKE AND ERICA LIKE AMERICA'; // We want to replace the name "ERICA" with "JON" and the word "AMERICA" with "PHP" echo str_replace($search, $replace, $subject); // output: "MIKE AND JON LIKE AMJON", which is not correct echo stro_replace($search, $replace, $subject); // output: "MIKE AND JON LIKE PHP", which is correct ?> ---- Server IP: 69.147.83.197 Probable Submitter: 216.177.196.194 ---- Manual Page -- http://www.php.net/manual/en/function.str-replace.php Edit -- https://master.php.net/note/edit/88569 Del: integrated -- https://master.php.net/note/delete/88569/integrated Del: useless -- https://master.php.net/note/delete/88569/useless Del: bad code -- https://master.php.net/note/delete/88569/bad+code Del: spam -- https://master.php.net/note/delete/88569/spam Del: non-english -- https://master.php.net/note/delete/88569/non-english Del: in docs -- https://master.php.net/note/delete/88569/in+docs Del: other reasons-- https://master.php.net/note/delete/88569 Reject -- https://master.php.net/note/reject/88569 Search -- https://master.php.net/manage/user-notes.php

« previous php.notes (#149944) next »