Function with custom pattern output [duplicate] - php

I'm having a hard time understanding when strtr would be preferable to str_replace or vice versa. It seems that it's possible to achieve the exact same results using either function, although the order in which substrings are replaced is reversed. For example:
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');
This outputs
YeXY XYring
YeZ Zring
YeXY XYring
YeZ Zring
Aside from syntax, is there any benefit to using one over the other? Any cases where one would not be sufficient to achieve a desired result?

First difference:
An interesting example of a different behaviour between strtr and str_replace is in the comments section of the PHP Manual:
<?php
$arrFrom = array("1","2","3","B");
$arrTo = array("A","B","C","D");
$word = "ZBB2";
echo str_replace($arrFrom, $arrTo, $word);
?>
I would expect as result: "ZDDB"
However, this return: "ZDDD"
(Because B = D according to our array)
To make this work, use "strtr" instead:
<?php
$arr = array("1" => "A","2" => "B","3" => "C","B" => "D");
$word = "ZBB2";
echo strtr($word,$arr);
?>
This returns: "ZDDB"
This means that str_replace is a more global approach to replacements, while strtr simply translates the chars one by one.
Another difference:
Given the following code (taken from 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);
?>
The resulting lines of text will be:
string(3) "PHP"
string(27) "PHP: Hypertext Preprocessor"
The main explanation:
This happens because:
strtr: it sorts its parameters by length, in descending order, so:
it will give "more importance" to the largest one, and then, as the subject text is itself the largest key of the replacement array, it gets translated.
because all the chars of the subject text have been replaced, the process ends there.
str_replace: it works in the order the keys are defined, so:
it finds the key “PHP” in the subject text and replaces it with: “PHP: Hypertext Preprocessor”, what gives as result:
“PHP: Hypertext Preprocessor: Hypertext Preprocessor”.
then it finds the next key: “PHP: Hypertext Preprocessor” in the resulting text of the former step, so it gets replaced by "PHP", which gives as result:
“PHP: Hypertext Preprocessor”.
there are no more keys to look for, so the replacement ends there.

It seems that it's possible to achieve the exact same results using either function
That's not always true and depends on the search and replace data you provide. For example where the two function differ see: Does PHP str_replace have a greater than 13 character limit?
strtr will not replace in parts of the string that already have been replaced - str_replace will replace inside replaces.
strtr will start with the longest key first in case you call it with two parameters - str_replace will replace from left to right.
str_replace can return the number of replacements done - strtr does not offer such a count value.

I think strtr provides more flexible and conditional replacement when used with two arguments, for example: if string is 1, replace with a, but if string is 10, replace with b. This trick could only be achieved by strtr.
$string = "1.10.0001";
echo strtr($string, array("1" => "a", "10" => "b"));
// a.b.000a
see : Php Manual Strtr.

Notice in manual
STRTR--
Description
string strtr ( string $str , string $from , string $to )
string strtr ( string $str , array $replace_pairs )
If given three arguments, this function returns a copy of str where ...
STR_REPLACE--
...
If search or replace are arrays, their elements are processed first to last.
...
STRTR each turn NOT effect to next, BUT STR_REPLACE does.

Related

PHP: preg_replace only first matching string in array

I've started with preg_replace in PHP and I wonder how I can replace only first matching array key with a specified array value cause I set preg_replace number of changes parameter to '1' and it's changing more than one time anyways. I also splitted my string to single words and I'm examining them one by one:
<?php
$internal_message = 'Hey, this is awesome!';
$words = array(
'/wesome(\W|$)/' => 'wful',
'/wful(\W|$)/' => 'wesome',
'/^this(\W|$)/' => 'that',
'/^that(\W|$)/' => 'this'
);
$splitted_message = preg_split("/[\s]+/", $internal_message);
$words_num = count($splitted_message);
for($i=0; $i<$words_num; $i++) {
$splitted_message[$i] = preg_replace(array_keys($words), array_values($words), $splitted_message[$i], 1);
}
$message = implode(" ", $splitted_message);
echo $message;
?>
I want this to be on output:
Hey, that is awful
(one suffix change, one word change and stops)
Not this:
Hey, this is awesome
(two suffix changes, two word changes and back to original word & suffix...)
Maybe I can simplify this code? I also can't change order of the array keys and values cause there will be more suffixes and single words to change soon. I'm kinda newbie in php coding and I'll be thankful for any help ;>
You may use plain text in the associative array keys that you will use to create dynamic regex patterns from, and use preg_replace_callback to replace the found values with the replacements in one go.
$internal_message = 'Hey, this is awesome!';
$words = array(
'wesome' => 'wful',
'wful' => 'wesome',
'this' => 'that',
'that' => 'this'
);
$rx = '~(?:' . implode("|", array_keys($words)) . ')\b~';
echo "$rx\n";
$message = preg_replace_callback($rx, function($m) use ($words) {
return isset($words[$m[0]]) ? $words[$m[0]] : $m[0];
}, $internal_message);
echo $message;
// => Hey, that is awful!
See the PHP demo.
The regex is
~(?:wesome|wful|this|that)\b~
The (?:wesome|wful|this|that) is a non-capturing group that matches any of the values inside, and \b is a word boundary, a non-consuming pattern that ensures there is no letter, digit or _ after the suffix.
The preg_replace_callback parses the string once, and when a match occurs, it is passed to the anonymous function (function($m)) together with the $words array (use ($words)) and if the $words array contains the found key (isset($words[$m[0]])) the corresponding value is returned ($words[$m[0]]) or the found match is returned otherwise ($m[0]).

Unable to echo the real value of a variable

Iam given the following variable: %4$s that outputs the text "a test" in the code.
I am trying to echo strlen('%4$s'); but it always returns 4 , while adding it as echo strlen("%4$s"); is not returning again the real value (2), which in my opinion means that for some reason, is uses the number of the variable.
My primary scope is to check if %4$s contains two or more words or to count the characters of a returned string.
At this time, %4$s , returns 'a test' in my HTML, so I m expecting an echo of %4$s to return 'a test' in PHP and a strlen of %4$s to return number 6
It looks like you are using a string format suitable for something like printf() or sprintf() and you are wanting to know the length of the 4th entered value.
Sample code:
$format = '%4$s';
$val1 = 'one';
$val2 = 'two';
$val3 = 'three';
$val4 = 'a test';
echo sprintf($format,$val1,$val2,$val3,$val4);
Which will display:
a test
And you want to know the length of that 4th value. Instead of strlen('%4$s'), you should be doing strlen($val4), for example:
echo strlen($val4);
Which will show:
6
A full example would be:
$format = '%5$d is the strlen of "%4$s"';
$val1 = 'one';
$val2 = 'two';
$val3 = 'three';
$val4 = 'a test';
echo sprintf($format,$val1,$val2,$val3,$val4,strlen($val4));
Which will display:
6 is the strlen of "a test"
Edit: It is still not very clear what you are doing even after looking at the pastebin link you posted. That said, the following is a guess that works. It uses the vsprintf() method:
$format = '%6$s is the strlen of "%4$s"';
$retArr[0] = array('post_id' => 'one',
'icon' => 'two',
'title' => 'three',
'permalink' => 'a test',
'image' => '/path/to/img.png');
$retArr[0]['len'] = strlen($retArr[0]['permalink']);
echo vsprintf($format,$retArr[0]);
And still outputs:
6 is the strlen of "a test"
Referring : http://php.net/manual/en/language.types.string.php
Note: Unlike the double-quoted and heredoc syntaxes, variables and escape sequences for special characters will not be expanded when they occur in single quoted strings.
Double quoted ¶
If the string is enclosed in double-quotes ("), PHP will interpret the following escape sequences for special characters:
$
is an escape character in php and if you don't escape it correctly using "\" like "\$s" "s" will be treated as a variable "$s".
Hence you are getting count as 2
strlen returns the amount of letters in a string so that's why you are getting the number 4 instead of your string.
try : '%4'.$s
Here's an answer that will count string length (by char) and do a word count.
Note: This isn't a copy-and-paste solution, so you will need to change your code to fit.
You can get the word count easily by doing the generic rule that words are separated by spaces. Here's where a PHP function called explode() comes in. We can use that combined with count() to get the word count:
$foo = 'a test';
$wordCount = count(explode(' ', $foo));
$strLength = strlen($foo);
echo $wordCount; # will output 2
echo $strLength; # will output 6
I've seen your pastebin for your array data, you can just loop through the array to get the individual values or use $array[$key] to specify a certain value to target.

Extract first integer in a string with PHP

Consider the following strings:
$strings = array(
"8.-10. stage",
"8. stage"
);
I would like to extract the first integer of each string, so it would return
8
8
I tried to filter out numbers with preg_replace but it returns all integers and I only want the first.
foreach($strings as $string)
{
echo preg_replace("/[^0-9]/", '',$string);
}
Any suggestions?
A convenient (although not record-breaking in performance) solution using regular expressions would be:
$string = "3rd time's a charm";
$filteredNumbers = array_filter(preg_split("/\D+/", $string));
$firstOccurence = reset($filteredNumbers);
echo $firstOccurence; // 3
Assuming that there is at least one number in the input, this is going to print the first one.
Non-digit characters will be completely ignored apart from the fact that they are considered to delimit numbers, which means that the first number can occur at any place inside the input (not necessarily at the beginning).
If you want to only consider a number that occurs at the beginning of the string, regex is not necessary:
echo substr($string, 0, strspn($string, "0123456789"));
preg_match('/\d+/',$id,$matches);
$id=$matches[0];
If the integer is always at the start of the string:
(int) $string;
If not, then strpbrk is useful for extracting the first non-negative number:
(int) strpbrk($string, "0123456789");
Alternatives
These one-liners are based on preg_split, preg_replace and preg_match:
preg_split("/\D+/", " $string")[1];
(int) preg_replace("/^\D+/", "", $string);
preg_match('/\d+/', "$string 0", $m)[0];
Two of these append extra character(s) to the string so empty strings or strings without numbers do not cause problems.
Note that these alternative solutions are for extracting non-negative integers only.
Try this:
$strings = array(
"8.-10. stage",
"8. stage"
);
$res = array();
foreach($strings as $key=>$string){
preg_match('/^(?P<number>\d)/',$string,$match);
$res[$key] = $match['number'];
}
echo "<pre>";
print_r($res);
foreach($strings as $string){
if(preg_match("/^(\d+?)/",$string,$res)) {
echo $res[1].PHP_EOL;
}
}
if you have Notice in PHP 7 +
Notice: Only variables should be passed by reference in YOUR_DIRECTORY_FILE.php on line LINE_NUMBER
By using this code
echo reset(array_filter(preg_split("/\D+/", $string)));
Change code to
$var = array_filter(preg_split("/\D+/", $string));
return reset($var);
And enjoy! Best Regards Ovasapov
How to filter out all characters except for the first occurring whole integer:
It is possible that the target integer is not at the start of the string (even if the OP's question only provides samples that start with an integer -- other researchers are likely to require more utility ...like the pages that I closed today using this page). It is also possible that the input contains no integers, or no leading / no trailing non-numeric characters.
The following is a regex expression has two checks:
It targets all non-numeric characters from the start of the string -- it stops immediately before the first encountered digit, if there is one at all.
It matches/consumes the first encountered whole integer, then immediatelly forgets/releases it (using \K) before matching/consuming ANY encountered characters in the remainder of the string.
My snippet will make 0, 1, or 2 replacements depending on the quality of the string.
Code: (Demo)
$strings = [
'stage', // expect empty string
'8.-10. stage', // expect 8
'8. stage', // expect 8
'8.-10. stage 1st', // expect 8
'Test 8. stage 2020', // expect 8
'Test 8.-10. stage - 2020 test', // expect 8
'A1B2C3D4D5E6F7G8', // expect 1
'1000', // expect 1000
'Test 2020', // expect 2020
];
var_export(
preg_replace('/^\D+|\d+\K.*/', '', $strings)
);
Or: (Demo)
preg_replace('/^\D*(\d+).*/', '$1', $strings)
Output:
array (
0 => '',
1 => '8',
2 => '8',
3 => '8',
4 => '8',
5 => '8',
6 => '1',
7 => '1000',
8 => '2020',
)

How do I replace certain parts of my string?

How can I replace a certain part of my string with another one?
Input string:
"Hello, my name is Santa"
How can I change all a's in my string with something else?
I think I need a foreach loop, but I'm unsure how to use it.
strtr ($str, array ('a' => '<replacement>'));
Or to answer your question more precisely:
strtr ("Hello, my name is Santa", array ('a' => '<replacement>'));
Search & Replace
There are a few different functions/methods to replace a certain part of a string with something else, all with their own advantages.
##str_replace() method (binary safe; case-sensitive)
Arguments
mixed str_replace ( mixed $search , mixed $replace , mixed $subject [, int &$count ] )
str_replace() has 3 required arguments as you can see in the above definition with the correct order, all of which can take a string as also an array as argument!
Search & Replace
search(string) AND replace(string) → Replaces the search string with the replace string.
search(array) AND replace(string) → Replaces all search elements with the replace string.
search(string) AND replace(array) → Throws you a notice: "Notice: Array to string conversion", because a replacement array for just one search string doesn't make sense, so it tries to convert the array to a string.
search(array) AND replace(array) → Replaces each search element with the corresponding replace element (Keys are ignored!).
search(more elements) AND replace(less elements) → Replaces each search element with the corresponding replace element (For the missing replace elements an empty string will be used).
search(less elements) AND replace(more elements) → Replaces each search element with the corresponding replace element (Unneeded replace elements are ignored).
Subject
subject(string) → Replacement is done for the subject string.
subject(array) → Replacement is done for each array element.
Code
echo str_replace("search", "replace", "text search text");
echo str_replace(["t", "a"], "X", "text search text");
echo str_replace("search", ["replace1", "replace2"], "text search text");
echo str_replace(["a", "c"], ["X", "Y"], "text search text");
Output
text replace text
XexX seXrch XexX
Notice: Array to string conversion
text seXrYh text
Notes
Gotcha!
Important to know is that str_replace() works from left to right of the array. This means it can possible replace a value which you already replaced. For example:
echo str_replace(array("a", "b"), array("b", "c"), "aabb");
//Probably expected output: bbcc
//Actual output: cccc
Case insensitive
If you want to make the search case insensitive you can use str_ireplace() (Notice the i for case-insensitive).
Multidimensional array
str_replace()/str_ireplace() does NOT work for multidimensional arrays. See this manual comment for such an implementation. Of course you can also replace str_replace() with str_ireplace() for case-insensitive.
If you want to put everything together and create a function that also works for multidimensional arrays case-insensitive you can do something like this:
<?php
function str_ireplace_deep($search, $replace, $subject)
{
if (is_array($subject))
{
foreach($subject as &$oneSubject)
$oneSubject = str_ireplace_deep($search, $replace, $oneSubject);
unset($oneSubject);
return $subject;
} else {
return str_ireplace($search, $replace, $subject);
}
}
?>
##strtr() method (50% binary safe; case-sensitive)
Arguments
string strtr ( string $str , string $from , string $to )
string strtr ( string $str , array $replace_pairs )
The function either takes 3 arguments with a from and to string or it takes 2 arguments with a replacement array array("search" => "replace" /* , ... */), all of which you can see in the above definition with the correct order.
2 Arguments
It starts to replace the longest key with the corresponding value and does this until it replaced all key => value pairs. In this case the function is binary safe, since it uses the entire key/value.
3 Arguments
It replaces the from argument with the to argument in the subject byte by byte. So it is not binary safe!
If the from and to arguments are of unequal length the replacement will stop when it reaches the end of the shorter string.
Subject
It doesn't accept an array as subject, just a string.
Code
echo strtr("text search text", "ax", "XY");;
echo strtr("text search text", ["search" => "replace"]);
Output
teYt seXrch teYt
text replace text
Notes
Gotcha!
Opposed to str_replace(), strtr() does NOT replace replaced strings. As an example:
echo strtr("aabb", ["a" => "b", "b" => "c"]);
//If expecting to replace replacements: cccc
//Actual output: bbcc
Also if you want to replace multiple things with the same string you can use array_fill_keys() to fill up your replacement array with the value.
Case insensitive
strtr() is NOT case-insensitive NOR is there a case-insensitive equivalent function. See this manual comment for a case-insensitive implementation.
Multidimensional array
strtr() does opposed to str_replace() NOT work with arrays as subject, so it also does NOT work with multidimensional arrays. You can of course use the code above from str_replace() for multidimensional arrays and just use it with strtr() or the implementation of stritr().
If you want to put everything together and create a function that also works for multidimensional arrays case-insensitive you can do something like this:
<?php
if(!function_exists("stritr")){
function stritr($string, $one = NULL, $two = NULL){
/*
stritr - case insensitive version of strtr
Author: Alexander Peev
Posted in PHP.NET
*/
if( is_string( $one ) ){
$two = strval( $two );
$one = substr( $one, 0, min( strlen($one), strlen($two) ) );
$two = substr( $two, 0, min( strlen($one), strlen($two) ) );
$product = strtr( $string, ( strtoupper($one) . strtolower($one) ), ( $two . $two ) );
return $product;
}
else if( is_array( $one ) ){
$pos1 = 0;
$product = $string;
while( count( $one ) > 0 ){
$positions = array();
foreach( $one as $from => $to ){
if( ( $pos2 = stripos( $product, $from, $pos1 ) ) === FALSE ){
unset( $one[ $from ] );
}
else{
$positions[ $from ] = $pos2;
}
}
if( count( $one ) <= 0 )break;
$winner = min( $positions );
$key = array_search( $winner, $positions );
$product = ( substr( $product, 0, $winner ) . $one[$key] . substr( $product, ( $winner + strlen($key) ) ) );
$pos1 = ( $winner + strlen( $one[$key] ) );
}
return $product;
}
else{
return $string;
}
}/* endfunction stritr */
}/* endfunction exists stritr */
function stritr_deep($string, $one = NULL, $two = NULL){
if (is_array($string))
{
foreach($string as &$oneSubject)
$oneSubject = stritr($string, $one, $two);
unset($oneSubject);
return $string;
} else {
return stritr($string, $one, $two);
}
}
?>
##preg_replace() method (binary safe; case-sensitive)
Arguments
mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )
preg_replace() has 3 required parameters in the order shown above. Now all 3 of them can take a string as also an array as argument!
Search & Replace
search(string) AND replace(string) → Replaces all matches of the search regex with the replace string.
search(array) AND replace(string) → Replaces all matches of each search regex with the replace string.
search(string) AND replace(array) → Throws you a warning: "Warning: preg_replace(): Parameter mismatch, pattern is a string while replacement is an array", because a replacement array for just one search regex doesn't make sense.
search(array) AND replace(array) → Replaces all matches of each search regex with the corresponding replace element(Keys are ignored!).
search(more elements) AND replace(less elements) → Replaces all matches of each search regex with the corresponding replace element(For the missing replace elements an empty string will be used).
search(less elements) AND replace(more elements) → Replaces all matches of each search regex with the corresponding replace element(Unneeded replace elements are ignored).
Subject
subject(string) → Replacement is done for the subject string.
subject(array) → Replacement is done for each array element.
Please note again: The search must be a regular expression! This means it needs delimiters and special characters need to be escaped.
Code
echo preg_replace("/search/", "replace", "text search text");
echo preg_replace(["/t/", "/a/"], "X", "text search text");
echo preg_replace("/search/", ["replace1", "replace2"], "text search text");
echo preg_replace(["a", "c"], ["X", "Y"], "text search text");
Output
text replace text
XexX seXrch XexX
Warning: preg_replace(): Parameter mismatch, pattern is a string while replacement is an array
text seXrYh text
Notes
Gotcha!
Same as str_replace(), preg_replace() works from left to right of the array. This means it can possible replace a value which you already replaced. For example:
echo preg_replace(["/a/", "/b/"], ["b", "c"], "aabb");
//Probably expected output: bbcc
//Actual output: cccc
Case insensitive
Since the search argument is a regular expression you can simply pass the flag i for case-insensitive search.
Multidimensional array
preg_replace() does NOT work for multidimensional arrays.
Backreference
Be aware that you can use \\n/$n as backreference to your capturing groups of the regex. Where 0 is the entire match and 1-99 for your capturing groups.
Also if the backreference is immediately followed by a number you have to use \${n}.
Replacement / "The /e modifier is deprecated"
The replacement in preg_replace() can't use callback functions as replacements. So you have to use preg_replace_callback(). Same when you use the modifier e and get "Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead". See: Replace preg_replace() e modifier with preg_replace_callback
If you want to put everything together and create a function that also works for multidimensional arrays case-insensitive you can do something like this:
<?php
function preg_replace_deep($search, $replace, $subject)
{
if (is_array($subject))
{
foreach($subject as &$oneSubject)
$oneSubject = preg_replace_deep($search, $replace, $oneSubject);
unset($oneSubject);
return $subject;
} else {
return preg_replace($search, $replace, $subject);
}
}
?>
##Loops while / for / foreach method (NOT binary safe; case-sensitive)
Now of course besides all of those functions you can also use a simple loop to loop through the string and replace each search => replace pair which you have.
But this gets way more complex when you do it binary safe, case-insensitive and for multidimensional arrays than just using the functions above. So I won't include any examples here.
Affected String
Right now all methods shown above do the replacement over the entire string. But sometimes you want to replace something only for a certain part of your string.
For this you probably want to/can use substr_replace(). Or another common method is to use substr() and apply the replacement only on that particular substring and put the string together afterwards. Of course you could also modify your regex or do something else to not apply the replacement to the entire string.
str_replace is sufficient for simple replacement jobs (such as replacing a single letter), but the use of preg_replace is generally advised (if you want something more flexible or versatile), because it's flexible and versatile. And as the 'a' is just an example...:
$String = preg_replace('/<string>/','<replacement>',$String);
Or if you want multiple replacements at once:
$String = preg_replace(array('/<string 1>/','/<string 2>/'),array('<replacement 1>','<replacement 2>'),$String);
preg_replace can, unfortunately, be quite tricky to use. I recommend the following reads:
http://php.net/manual/en/function.preg-replace.php
http://www.phpro.org/tutorials/Introduction-to-PHP-Regex.html
Also, if you decide to use str_replace(), and your replacement needs to be case-sensitive, you're going to need str_ireplace().
This can work also without of any of PHP string functions, here changing your 'a' to '&' ampersand character:
for ($i=0; $i<strlen($str); $i++){
if ($str[$i] == 'a'){
$str[$i] = '&';
}
}
echo $str;
Use function preg_replace()
$text ='this is the old word';
echo $text;
echo '<br>';
$text = preg_replace('/\bold word\b/', 'NEW WORD', $text);
echo $text;

When to use strtr vs str_replace?

I'm having a hard time understanding when strtr would be preferable to str_replace or vice versa. It seems that it's possible to achieve the exact same results using either function, although the order in which substrings are replaced is reversed. For example:
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');
This outputs
YeXY XYring
YeZ Zring
YeXY XYring
YeZ Zring
Aside from syntax, is there any benefit to using one over the other? Any cases where one would not be sufficient to achieve a desired result?
First difference:
An interesting example of a different behaviour between strtr and str_replace is in the comments section of the PHP Manual:
<?php
$arrFrom = array("1","2","3","B");
$arrTo = array("A","B","C","D");
$word = "ZBB2";
echo str_replace($arrFrom, $arrTo, $word);
?>
I would expect as result: "ZDDB"
However, this return: "ZDDD"
(Because B = D according to our array)
To make this work, use "strtr" instead:
<?php
$arr = array("1" => "A","2" => "B","3" => "C","B" => "D");
$word = "ZBB2";
echo strtr($word,$arr);
?>
This returns: "ZDDB"
This means that str_replace is a more global approach to replacements, while strtr simply translates the chars one by one.
Another difference:
Given the following code (taken from 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);
?>
The resulting lines of text will be:
string(3) "PHP"
string(27) "PHP: Hypertext Preprocessor"
The main explanation:
This happens because:
strtr: it sorts its parameters by length, in descending order, so:
it will give "more importance" to the largest one, and then, as the subject text is itself the largest key of the replacement array, it gets translated.
because all the chars of the subject text have been replaced, the process ends there.
str_replace: it works in the order the keys are defined, so:
it finds the key “PHP” in the subject text and replaces it with: “PHP: Hypertext Preprocessor”, what gives as result:
“PHP: Hypertext Preprocessor: Hypertext Preprocessor”.
then it finds the next key: “PHP: Hypertext Preprocessor” in the resulting text of the former step, so it gets replaced by "PHP", which gives as result:
“PHP: Hypertext Preprocessor”.
there are no more keys to look for, so the replacement ends there.
It seems that it's possible to achieve the exact same results using either function
That's not always true and depends on the search and replace data you provide. For example where the two function differ see: Does PHP str_replace have a greater than 13 character limit?
strtr will not replace in parts of the string that already have been replaced - str_replace will replace inside replaces.
strtr will start with the longest key first in case you call it with two parameters - str_replace will replace from left to right.
str_replace can return the number of replacements done - strtr does not offer such a count value.
I think strtr provides more flexible and conditional replacement when used with two arguments, for example: if string is 1, replace with a, but if string is 10, replace with b. This trick could only be achieved by strtr.
$string = "1.10.0001";
echo strtr($string, array("1" => "a", "10" => "b"));
// a.b.000a
see : Php Manual Strtr.
Notice in manual
STRTR--
Description
string strtr ( string $str , string $from , string $to )
string strtr ( string $str , array $replace_pairs )
If given three arguments, this function returns a copy of str where ...
STR_REPLACE--
...
If search or replace are arrays, their elements are processed first to last.
...
STRTR each turn NOT effect to next, BUT STR_REPLACE does.

Categories