str_replace
(PHP 4, PHP 5, PHP 7, PHP 8)
str_replace — 検索文字列に一致したすべての文字列を置換する
説明
array|string
$search
,array|string
$replace
,string|array
$subject
,int
&$count
= null
): string|array
この関数は、subject
の中の
search
を全て
replace
に置換します。
固定の文字列ではなく、パターンベースでテキストを置換したい場合、 preg_replace() を使ってください。
パラメータ
search
と replace
が配列の場合、str_replace() は各配列から値をひとつ取り出し、
subject
上で検索と置換を行うために使用します。
replace
の値が
search
よりも少ない場合、
置換される値の残りの部分には空の文字列が使用されます。
search
が配列で
replace
が文字列の場合、この置換文字列が
search
の各値について使用されます。しかし、
逆は意味がありません。
search
あるいは replace
が配列の場合は、配列の最初の要素から順に処理されます。
search
-
探したい値。needle (針) と呼ばれることもあります。 配列を使えば、複数の値を指定することもできます。
replace
-
見つかった
search
を置き換える値。 配列を使えば、複数の値を指定することもできます。 subject
-
検索・置換の対象となる文字列あるいは配列。 haystack (干し草の山) と呼ばれることもあります。
subject
が配列の場合、subject
の各エントリについて検索と置換が行われ、 戻り値は同様に配列となります。 count
-
指定した場合は、マッチして置換が行われた箇所の個数がここに格納されます。
戻り値
この関数は、置換後の文字列あるいは配列を返します。
例
例1 基本的な str_replace() の例
<?php
// <body text='black'> となります
$bodytag = str_replace("%body%", "black", "<body text='%body%'>");
// Hll Wrld f PHP となります
$vowels = array("a", "e", "i", "o", "u", "A", "E", "I", "O", "U");
$onlyconsonants = str_replace($vowels, "", "Hello World of PHP");
// You should eat pizza, beer, and ice cream every day となります
$phrase = "You should eat fruits, vegetables, and fiber every day.";
$healthy = array("fruits", "vegetables", "fiber");
$yummy = array("pizza", "beer", "ice cream");
$newphrase = str_replace($healthy, $yummy, $phrase);
// 2 となります
$str = str_replace("ll", "", "good golly miss molly!", $count);
echo $count;
?>
例2 str_replace() に関するちょっとした事実
<?php
// 置換の順番を指定します
$str = "Line 1\nLine 2\rLine 3\r\nLine 4\n";
$order = array("\r\n", "\n", "\r");
$replace = '<br />';
// まず最初に \r\n を置換するので、二重に変換されることはありません
$newstr = str_replace($order, $replace, $str);
// 出力は F となります。A が B に、そして B が C に、そして……
// 最終的に E が F に置換されるからです。置換は左から右へと順に行われます
$search = array('A', 'B', 'C', 'D', 'E');
$replace = array('B', 'C', 'D', 'E', 'F');
$subject = 'A';
echo str_replace($search, $replace, $subject);
// 出力は apearpearle pear となります
// 上で説明したのと同じ理由です
$letters = array('a', 'p');
$fruit = array('apple', 'pear');
$text = 'a p';
$output = str_replace($letters, $fruit, $text);
echo $output;
?>
注意
注意: この関数はバイナリデータに対応しています。
置換の順番に関するメモ
str_replace() は左から右へと置換を行うので、 複数の置換を行うときには、前に追加された値を置換する可能性もあります。 このドキュメントのサンプルを参照ください。
注意:
この関数は大文字小文字を区別します。区別せずに置換するには str_ireplace() を使用します。
参考
- str_ireplace() - 大文字小文字を区別しない str_replace
- substr_replace() - 文字列の一部を置換する
- preg_replace() - 正規表現検索および置換を行う
- strtr() - 文字の変換あるいは部分文字列の置換を行う
User Contributed Notes 33 notes
A faster way to replace the strings in multidimensional array is to json_encode() it, do the str_replace() and then json_decode() it, like this:
<?php
function str_replace_json($search, $replace, $subject){
return json_decode(str_replace($search, $replace, json_encode($subject)));
}
?>
This method is almost 3x faster (in 10000 runs.) than using recursive calling and looping method, and 10x simpler in coding.
Compared to:
<?php
function str_replace_deep($search, $replace, $subject)
{
if (is_array($subject))
{
foreach($subject as &$oneSubject)
$oneSubject = str_replace_deep($search, $replace, $oneSubject);
unset($oneSubject);
return $subject;
} else {
return str_replace($search, $replace, $subject);
}
}
?>
To remove all characters from string $b that exist in string $a:
$a="ABC";
$b="teAsBtC";
echo str_replace(str_split($a),'',$b);
Output: test
To remove all characters from string $b that don't exist in string $a:
$a="ABC";
$b="teAsBtC";
echo str_replace(str_split(str_replace(str_split($a),'',$b)),'',$b);
Output: ABC
Be careful when replacing characters (or repeated patterns in the FROM and TO arrays):
For example:
<?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"
Note that this does not replace strings that become part of replacement strings. This may be a problem when you want to remove multiple instances of the same repetative pattern, several times in a row.
If you want to remove all dashes but one from the string '-aaa----b-c-----d--e---f' resulting in '-aaa-b-c-d-e-f', you cannot use str_replace. Instead, use preg_replace:
<?php
$challenge = '-aaa----b-c-----d--e---f';
echo str_replace('--', '-', $challenge).'<br>';
echo preg_replace('/--+/', '-', $challenge).'<br>';
?>
This outputs the following:
-aaa--b-c---d-e--f
-aaa-b-c-d-e-f
"If search is an array and replace is a string, then this replacement string is used for every value of search. The converse would not make sense, though. "
I think one important (and not at all vaguely theoretical) use-case is completely ignored here. Take, for example, the way the PDO handles parameter replacement.
If we have the following query:
"SELECT * FROM my_table WHERE (id = ? AND my_column = ? AND other_column = ?);"
The "?"s should be replaced by each successive variable in a $parameters array. That is EXACTLY the use case for "search" being a value and "replace" being an array.
Considering that this is not only a real-world example but also part of a core PHP functionality I find it very strange that it's dismissed so easily here.
Feel free to optimize this using the while/for or anything else, but this is a bit of code that allows you to replace strings found in an associative array.
For example:
<?php
$replace = array(
'dog' => 'cat',
'apple' => 'orange'
'chevy' => 'ford'
);
$string = 'I like to eat an apple with my dog in my chevy';
echo str_replace_assoc($replace,$string);
// Echo: I like to eat an orange with my cat in my ford
?>
Here is the function:
<?php
function strReplaceAssoc(array $replace, $subject) {
return str_replace(array_keys($replace), array_values($replace), $subject);
}
?>
[Jun 1st, 2010 - EDIT BY thiago AT php DOT net: Function has been replaced with an updated version sent by ljelinek AT gmail DOT com]
Decision to avoid problem "it might replace a previously inserted value when doing multiple replacements. See also the examples in this document."
$urls - array of urls i want to replace with tag <a> and urls could be similar
http://abc.com/parameter/
http://abc.com/
// at first sort by length to have longest firstly
usort($urls,'sortByLen');
$replaces=[];
// replace all urls with unique
foreach($urls as $url){
$replace = '__REPLACE' . uniqid() . '__';
$text = str_replace($url,$replace, $text);
$replaces[$replace] = '<a href="' . $url . '">' . $url . '</a>';
}
foreach($replaces as $key => $replace){
$text = str_replace($key,$replace, $text);
}
--------------
function sortByLen($a,$b){
return strlen($b)-strlen($a);
}
Hope it will help others like me
This is what happens when the search and replace arrays are different sizes:
<?php
$search = array('a', 'b', 'c', 'd', 'e');
$replace = array('A', 'B', 'C');
$subject = 'abcdefg';
echo str_replace($search, $replace, $subject);
// result: 'ABCfg'
$search = array('a', 'b', 'c');
$replace = array('A', 'B', 'C', 'D', 'E');
$subject = 'abcdefg';
echo str_replace($search, $replace, $subject);
// result: 'ABCdefg'
?>
No warning or error is generated in either of these cases.
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(' ', '&');
$subject = 'Hello & goodbye!';
// We want to replace the spaces with and the ampersand with &
echo str_replace($search, $replace, $subject); // output: "Hello&nbsp&&nbspgoodbye!" - wrong!
echo stro_replace($search, $replace, $subject); // output: "Hello & 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
?>
nikolaz dot tang at hotmail dot com's solution of using json_encode/decode is interesting, but a couple of issues to be aware of with it.
<?php
// From: nikolaz dot tang at hotmail dot com's post
function str_replace_json($search, $replace, $subject){
return json_decode(str_replace($search, $replace, json_encode($subject)));
}
?>
json_decode will return objects, where arrays are probably expected. This is easily remedied by adding 2nd parameter 'true' to json_decode.
$search and $replace could contain strings that match json encoding, which will either change the structure returned by this method, or break the json.
ie:
<?php
var_dump(str_replace_json('":"', '","', ['this' => 'stuff']));
var_dump(str_replace_json('this":"', 'this" : "thing", "with":"', ['this' => 'stuff']));
?>
Be aware that if you use this for filtering & sanitizing some form of user input, or remove ALL instances of a string, there's another gotcha to watch out for:
// Remove all double characters
$string="1001011010";
$string=str_replace(array("11","00"),"",$string);
// Output: "110010"
$string="<ht<html>ml> Malicious code </<html>html> etc";
$string=str_replace(array("<html>","</html>"),"",$string);
// Output: "<html> Malicious code </html> etc"
If we have a html template that contains placeholders in curly braces that need to be replaced in runtime, the following function will do it using str_replace:
<?php
function parse_template($filename, $data) {
// example template variables {a} and {bc}
// example $data array
// $data = Array("a" => 'one', "bc" => 'two');
$q = file_get_contents($filename);
foreach ($data as $key => $value) {
$q = str_replace('{'.$key.'}', $value, $q);
}
return $q;
}
?>
Might be worth mentioning that a SIMPLE way to accomplish Example 2 (potential gotchas) is to simply start your "replacements" in reverse.
So instead of starting from "A" and ending with "E":
<?php
$search = array('A', 'B', 'C', 'D', 'E');
$replace = array('B', 'C', 'D', 'E', 'F');
// replaces A to B, B to C, C to D, D to E, E to F (makes them all F)
// start from "E" and end with "A":
$search = array('E', 'D', 'C', 'B', 'A');
$replace = array('F', 'E', 'D', 'C', 'B');
// replaces E to F, D to E, C to D, B to C, A to B (prevents from
// multiple replacements of already replaced values)
?>
So basically start from the "end" and put the replacements in an order where the "replaced value" won't equal a value that exists later in the "search array".
This strips out horrible MS word characters.
Just keep fine tuning it until you get what you need, you'll see ive commented some out which caused problems for me.
There could be some that need adding in, but its a start to anyone who wishes to make their own custom function.
<?php
function msword_conversion($str)
{
$str = str_replace(chr(130), ',', $str); // baseline single quote
$str = str_replace(chr(131), 'NLG', $str); // florin
$str = str_replace(chr(132), '"', $str); // baseline double quote
$str = str_replace(chr(133), '...', $str); // ellipsis
$str = str_replace(chr(134), '**', $str); // dagger (a second footnote)
$str = str_replace(chr(135), '***', $str); // double dagger (a third footnote)
$str = str_replace(chr(136), '^', $str); // circumflex accent
$str = str_replace(chr(137), 'o/oo', $str); // permile
$str = str_replace(chr(138), 'Sh', $str); // S Hacek
$str = str_replace(chr(139), '<', $str); // left single guillemet
// $str = str_replace(chr(140), 'OE', $str); // OE ligature
$str = str_replace(chr(145), "'", $str); // left single quote
$str = str_replace(chr(146), "'", $str); // right single quote
// $str = str_replace(chr(147), '"', $str); // left double quote
// $str = str_replace(chr(148), '"', $str); // right double quote
$str = str_replace(chr(149), '-', $str); // bullet
$str = str_replace(chr(150), '-–', $str); // endash
$str = str_replace(chr(151), '--', $str); // emdash
// $str = str_replace(chr(152), '~', $str); // tilde accent
// $str = str_replace(chr(153), '(TM)', $str); // trademark ligature
$str = str_replace(chr(154), 'sh', $str); // s Hacek
$str = str_replace(chr(155), '>', $str); // right single guillemet
// $str = str_replace(chr(156), 'oe', $str); // oe ligature
$str = str_replace(chr(159), 'Y', $str); // Y Dieresis
$str = str_replace('°C', '°C', $str); // Celcius is used quite a lot so it makes sense to add this in
$str = str_replace('£', '£', $str);
$str = str_replace("'", "'", $str);
$str = str_replace('"', '"', $str);
$str = str_replace('–', '–', $str);
return $str;
}
?>
As an effort to remove those Word copy and paste smart quotes, I've found that this works with UTF8 encoded strings (where $text in the following example is UTF8). Also the elipsis and em and en dashes are replaced.
There is an "invisible" character after the †for the right side double smart quote that doesn't seem to display here. It is chr(157).
<?php
$find[] = '“'; // left side double smart quote
$find[] = 'â€'; // right side double smart quote
$find[] = '‘'; // left side single smart quote
$find[] = '’'; // right side single smart quote
$find[] = '…'; // elipsis
$find[] = '—'; // em dash
$find[] = '–'; // en dash
$replace[] = '"';
$replace[] = '"';
$replace[] = "'";
$replace[] = "'";
$replace[] = "...";
$replace[] = "-";
$replace[] = "-";
$text = str_replace($find, $replace, $text);
?>
Here's a deep replace function allowing multi-dimensional arrays in $search, $replace and $subject. The keys and other structure of $subject are preserved.
<?php
// Auxiliary function:
function _replaceWithAnything($search,$replace,$subject){
if(!is_array($search) || !is_array($replace)){
$search=array($search);
$replace=array($replace);
}
$match=array_search($subject,$search,true);
if($match!==false && array_key_exists($match,$replace))
$subject=$replace[$match];
return $subject;
}
// Main function:
function deepReplace($search,$replace,$subject){
if(!is_array($subject))
return _replaceWithAnything($search,$replace,$subject);
foreach($subject as &$val){
if(is_array($val)){
$val=deepReplace($search,$replace,$val);
continue;
}
$val=_replaceWithAnything($search,$replace,$val);
}
return $subject;
}
?>