Yet another deep replace function:
<?php
function str_replace_deep( $search, $replace, $subject)
{
$subject = str_replace( $search, $replace, $subject);
foreach ($subject as &$value)
is_array( $value) and $value =str_replace_deep( $search, $replace, $value);
return $subject;
}
?>
str_replace
(PHP 4, PHP 5)
str_replace — 발견한 모든 검색 문자열을 치환 문자열로 교체합니다.
설명
subject 에서 발견한 모든 search 를 주어진 replace 값으로 치환한 문자열이나 배열을 반환합니다. (정규표현식처럼) 복잡한 치환 규칙이 필요하지 않다면, 항상 ereg_replace()나 preg_replace() 대신 이 함수를 사용해야 합니다.
PHP 4.0.5부터, str_replace()의 모든 인자를 array로 지정할 수 있습니다.
PHP 4.3.3 이전 버전에는 search 와 replace 인자에 모두 배열을 사용할 경우, 빈 search 인덱스를 replace 배열의 내부 포인터를 옮기지 않은 채 넘어가는 버그가 존재했습니다. PHP 4.3.3에서 수정했기에, 이 버그에 관련된 모든 스크립트는 이전의 동작을 하려면 이 함수를 호출 하기 전에 빈 search값을 제거해야 합니다.
subject 가 배열이면, 검색 및 치환을 subject 의 모든 원소에서 수행하고, 배열을 반환합니다.
search 와 replace 가 배열이면, str_replace()는 각각의 배열에서 가져온 값을 subject 의 검색과 치환에 사용합니다. replace 가 search 보다 적은 값을 가지면, 나머지 치환값은 빈 문자열을 사용합니다. search 가 배열이고 replace 가 문자열이면; 치환 문자열을 모든 search 값에 사용합니다.
Example#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);
// PHP 5.0.0부터 사용할 수있는 count 인자 사용
$str = str_replace("ll", "", "good golly miss molly!", $count);
echo $count; // 2
?>
Note: 이 함수는 바이너리 호환(binary-safe)입니다.
Note: PHP 5.0.0부터 매치하고 치환한 횟수를 참조로 전달하는 count 로 반환할 수 있습니다. PHP 5.0.0 이전에는 이 인자를 사용할 수 없습니다.
참고: str_ireplace(), substr_replace(), ereg_replace(), preg_replace(), strtr().
str_replace
22-Jun-2008 10:18
20-Jun-2008 04:52
On the 19th of June, 2008, max at bitsonnet dot com posted a function interpolate that used create_function. I'd never seen create_function before and I thought it was very educational. Thanks, Maxim!
However, the interpolate function can be improved, speed-wise:
<?php
function interpolate2($template, $hash, $prefix = '#{', $postfix = '}')
{
$tmp = array();
foreach($hash as $k => $v)
{
$tmp[$prefix . $k . $postfix] = $v;
}
return str_replace(array_keys($tmp), array_values($tmp), $template);
}
echo interpolate2('Hello, #{username}. Welcome to #{site}.', array('username' => 'World', 'site' => 'php.net'));
?>
According to my own tests, this version is somewhere between 4 and 5 times faster.
Note, btw, that I used a very similar function on the sprintf page.
19-Jun-2008 02:00
I always miss interpolate functionality in PHP, so I wrote this little helper method. It allows you to specify your own markup using $prefix and $postfix.
<?php
# Interpolate a string using hash.
# by Maxim Chernyak ( http://mediumexposure.com )
function interpolate($template, $hash, $prefix = '#{', $postfix = '}' ) {
$tokenize = create_function('$token', 'return "'. $prefix .'".$token."'.$postfix.'";');
$keys = array_keys($hash);
$values = array_values($hash);
$keys = array_map($tokenize, $keys);
return str_replace($keys, $values, $template);
}
?>
For example:
<?php
$result = interpolate('Hello, #{username}. Welcome to #{site}.', array('username' => 'Hakunin', 'site' => 'php.net'));
?>
27-Apr-2008 03:32
The example presented by bladescope at googlemail dot com has a couple of syntax errors. This works:
<?php
$template = "The {color} {object} is in {location}";
$array = array(
'{object}' => 'Ball',
'{color}' => 'Red',
'{location}' => 'The Playground',
);
foreach ($array as $search => $replace) {
$template = str_replace($search, $replace, $template);
}
print $template;
?>
I did not check it for speed or thoroughly test it, but this function seems to do the same thing more succinctly.
<?php
function template($array, $template) {
return str_replace(
array_keys($array),
array_values($array),
$template
);
}
echo template(
array(
'{color}' => 'red',
'{object}' => 'ball',
'{location}' => 'the playground',
),
'The {color} {object} is in {location}.'
);
?>
09-Aug-2007 12:50
This is the functions I wrote for the problem reported above, str_replace in multi-dimensional arrays. It can work with preg_replace as well.
<?php
function array_replace($SEARCH,$REPLACE,$INPUT) {
if (is_array($INPUT) and count($INPUT)<>count($INPUT,1)):
foreach($INPUT as $FAN):
$OUTPUT[]=array_replace($SEARCH,$REPLACE,$FAN);
endforeach;
else:
$OUTPUT=str_replace($SEARCH,$REPLACE,$INPUT);
endif;
return $OUTPUT;
}
?>
09-Aug-2007 12:22
With PHP 4.3.1, at least, str_replace works fine when working with single arrays but mess it all with two or more dimension arrays.
<?php
$subject = array("You should eat this","this","and this every day.");
$search = "this";
$replace = "that";
$new = str_replace($search, $replace, $subject);
print_r($new); // Array ( [0] => You should eat that [1] => that [2] => and that every day. )
echo "<hr />";
$subject = array(array("first", "You should eat this")
,array("second","this")
,array("third", "and this every day."));
$search = "this";
$replace = "that";
$new = str_replace($search, $replace, $subject);
print_r($new); // Array ( [0] => Array [1] => Array [2] => Array )
?>
22-Jul-2007 01:28
In order to replace carriage return characters from form inputs, if everything else fails, you can try:
<?php
$new_text = str_replace(chr(13).chr(10), '_', $original_text);
?>
And in order to show the line feeds in a javascript alert, you can do:
<?php
$new_text = str_replace(chr(13).chr(10), '\n', $original_text);
?>
12-Jun-2007 06:47
Here is a version that allows for empty multidimensional arrays:
<?php
function str_replace_array ($search, $replace, $subject) {
if (is_array($subject)) {
foreach ($subject as $id=>$inner_subject) {
$subject[$id]=str_replace_array($search, $replace, $inner_subject);
}
} else {
$subject=str_replace($search, $replace, $subject);
}
return $subject;
}
?>
05-Jun-2007 11:27
I found that having UTF-8 strings in as argument didnt
work for me using heavyraptors function.
Adding UTF-8 as argument on htmlentities
fixed the problem.
cheers, tim at hysniu.com
<?php
function replace_accents($str) {
$str = htmlentities($str, ENT_COMPAT, "UTF-8");
$str = preg_replace(
'/&([a-zA-Z])(uml|acute|grave|circ|tilde);/',
'$1',$str);
return html_entity_decode($str);
}
?>
25-Feb-2007 05:48
My input is MS Excel file but I want to save ‘,’,“,” as ',',",".
$badchr = array(
"\xc2", // prefix 1
"\x80", // prefix 2
"\x98", // single quote opening
"\x99", // single quote closing
"\x8c", // double quote opening
"\x9d" // double quote closing
);
$goodchr = array('', '', '\'', '\'', '"', '"');
str_replace($badchr, $goodchr, $strFromExcelFile);
Works for me.
16-Feb-2007 12:30
This is a more rigid alternative to spectrereturns at creaturestoke dot com's replace_different function:
<?php
function str_replace_many ($search, $replacements, $subject) {
$index = strlen($subject);
$replacements = array_reverse($replacements);
if (count($replacements) != substr_count($subject, $search)) {
return FALSE;
}
foreach ($replacements as $replacement) {
$index = strrpos(substr($subject, 0, $index), $search);
$prefix = substr($subject, 0, $index);
$suffix = substr($subject, $index + 1);
$subject = $prefix . $replacement . $suffix;
}
return $subject;
}
?>
This will return false if there are a different number of $replacements versus number of occurrences of $search in $subject. Additionally, $search much be exactly one character (if a string is provided, only the first character in the string will be used). Examples:
<?php
echo str_replace_many('?',array('Jane','banana'),'? is eating a ?.');
?>
prints: "Jane is eating a banana."
Before spending hours searching your application why it makes UTF-8 encoding into some malformed something with str_replace, make sure you save your PHP file in UTF-8 (NO BOM).
This was at least one of my problems.
27-Nov-2006 01:32
I create a little function to transform (to example) "User@example.net" in "user AT example DOT net" and conversely.
<?php
function code_mail($email) {
if(preg_match('`^.+@.+\..{1,5}$`', $email)) { //email format
$email = str_replace('.', ' DOT ', $email); //replace . by dot
$email = str_replace('@', ' AT ', $email); //replace @ by at
return $email;
}
else { //not email format
return false;
}
}
function decode_mail($email) { //on décode...
$email = str_replace(' DOT ', '.', $email); //replace dot by .
$email = str_replace(' AT ', '@', $email); //replace at by @
return $email;
}
?>
11-Nov-2006 03:14
This simple function may be usefull to convert czech text from cp-1250 encoding to iso-8859-2 (convert S, T and Z with caron).
I use it because mbstring does not support windows-1250 (i.e. mb_convert_encoding(win2iso($text), "utf-8", "iso-8859-2");).
<?php
function win2iso($text)
{
$win = array ("\x9A", "\x9D", "\x9E", "\x8A", "\x8D", "\x8E");
$iso = array ("\xB9", "\xBB", "\xBE", "\xA9", "\xAB", "\xAE");
return str_replace($win, $iso, $text);
}
?>
30-Jul-2006 06:50
You may have decided to save in a non ANSI format a file so that a few fancy chars that you plan to replace can be viewed by your human eyes too (aren't all those empty rectangles a curse?).
Fine. All works just fine in the file, and all the replacements occur as intended.
You make a class out of those codes.
Then you put this non ANSI encoded file in your includes folder. Isn't it a nice class?
Well, don't call in such class as an include into another file, if the latter is ANSI : the char look up tables will NOT match, and the latter file (say the caller) will (I guess) feed ANSI codes to the included file (say the called) and you will spend a day wondering why the class methods work 100% well when you perform replacements directly from within the called, and yet the very same methods, even with the very same copied-and-pasted examples, fail miserably when performed from within the caller.
A very "stimulating" debugging!
I just came out from a night spent on this. I just forgot the included class file wasn't saved as an ANSI.
<?php
class regexp{
//blah blah...
var $toascii=array( 'Ã' => 'A');
//blah blah
function toascii_replace($input, $addSlashes=0){
return (!$addSlashes)? strtr($input, $this->toascii): addslashes( strtr($input, $this->toascii) );
}
}
$r=new regexp();
$input='Ã';
print $r->toascii_replace($input);//prints A
?>
Now save that class (remove the print statement too) in a format that isn't ANSI, say UTF-8.
Then do:
<?php
include_once('regexp.php');
$r=new regexp();
$input='Ã';
print $r->toascii_replace($input);//prints... Ã
?>
IDENTICAL codes, different results.
note: the class uses strtr but would happen with all replacing oriented functions, and I can pester all the documentations. Maybe I worked out the wrong reason, but the behaviour occurs.
30-Mar-2006 07:40
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);
?>
11-Dec-2004 11:57
A simple function to take out the double line breaks "%0D%0A" from a string made from text being wrapped in a textarea and turn them into single line breaks.
<?php
function remove_extra_linebreaks($string) {
$new_string=urlencode ($string);
$new_string=ereg_replace("%0D", " ", $new_string);
$new_string=urldecode ($new_string);
return $new_string;
}
?>
I use it when taking text from a textarea with wrap="hard" that I'm emailing out on the next page, for instance. Otherwise there's an extra empty line between each line in the emailed text, which looks nasty!
25-Aug-2003 06:12
Take care with order when using arrays in replacement.
<?php
$match=array("ONE","TWO","THREE");
$replace=array("TWO WORDS","MANY LETTERS","OTHER IDEAS");
$sample="ONE SAMPLE";
echo str_replace($match,$replace,$sample);
?>
It will show: "MANY LETTERS WORDS SAMPLE"
That is, after replacing "ONE" with "TWO WORDS", process follows with next array item and it changes "TWO" with "MANY LETTERS".
27-Jun-2003 04:08
An excellent way of making sure your pages don't contain "invalid entities", IE. Valid HTML is using the following function.
Most forum packages / extensions provide output containing the symbol &, we don't want this!
<?php
function include_safe ($file)
{
$array = file($file);
foreach ($array as $line) {
print str_replace('&', '&', $line);
}
}
?>
The same technique could also be used in conjuntion with htmlmspecialchars or htmlentities.
Having a string for $search and an array for $replace won't work. This is mentioned on the preg_replace() page where it's described as not making sense, but not here.
But one could interpret such a situation and hence implement str_replace so that a signature of (string, array, string) or even (string, array, array) would "work". The result of
<?php
$search = '*';
$replace = range(1,20);
$subject = '{*}';
$result = str_replace($search, $replace, $subject);
?>
could be an array of elements "{1}", "{2}", "{3}" .... In other words it would have the same effect as
<?php
$search = '*';
$replace = range(1,20);
$subject = '{*}';
$result = array();
foreach($replace as $r) {
$result[] = str_replace($search, $r, $subject);
}
?>
I leave more elaborate applications to your imagination :)
The result of a str_replace(string,array,array) would therefore presumably be an array of arrays, with its dimensions indexed by the two arrays passed in. But then there's the question of which is the first dimension and which is the second.
07-Jan-2003 04:32
I was trying to remove newlines from a textarea input (result of failed submission of parent form - JS verification not possible in this situation) to send back to the textarea via javascript (due to the fact that setting the value in the textarea tag does not work) and had a hard time figuring it out.
If anyone cares, try replacing: "%0D%0A" which is how I found it(changed my POST method to GET) and tracked it down in the address bar of my browser. Hope this helps, I sure wish someone else had posted it earlier!
09-Oct-2002 03:26
To use one or two arrays in str_replace,
this appears to be the correct format:
<?php
str_replace(array('1st_current_needle_element', '2nd', '3rd'), array('1st_new_needle_element', '2nd', '3rd'), $haystack)
?>
Example of a single array, which simply removes the characters in the first array:
<?php
$text=str_replace(array('<', '>', '\\', '/', '='), "", $text);
?>
This will delete the chars: < > \ / =
It could also be done by first defining the array(s), like this:
<?php
$targetChars=array('<', '>', '\\', '/', '=');
$text=str_replace($targetChars, "", $text);
?>
