str_replace

(PHP 3 >= 3.0.6, PHP 4, PHP 5)

str_replace --  Replace all occurrences of the search string with the replacement string

Description

mixed str_replace ( mixed search, mixed replace, mixed subject [, int &count] )

This function returns a string or an array with all occurrences of search in subject replaced with the given replace value. If you don't need fancy replacing rules (like regular expressions), you should always use this function instead of ereg_replace() or preg_replace().

As of PHP 4.0.5, every parameter in str_replace() can be an array.

警告

In PHP versions prior to 4.3.3 a bug existed when using arrays as both search and replace parameters which caused empty search indexes to be skipped without advancing the internal pointer on the replace array. This has been corrected in PHP 4.3.3, any scripts which relied on this bug should remove empty search values prior to calling this function in order to mimick the original behavior.

If subject is an array, then the search and replace is performed with every entry of subject, and the return value is an array as well.

If search and replace are arrays, then str_replace() takes a value from each array and uses them to do search and replace on subject. If replace has fewer values than search, then an empty string is used for the rest of replacement values. 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.

例子 1. str_replace() examples

<?php
// Provides: <body text='black'>
$bodytag = str_replace("%body%", "black", "<body text='%body%'>");

// Provides: Hll Wrld f PHP
$vowels = array("a", "e", "i", "o", "u", "A", "E", "I", "O", "U");
$onlyconsonants = str_replace($vowels, "", "Hello World of PHP");

// Provides: 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);

// Use of the count parameter is available as of PHP 5.0.0
$str = str_replace("ll", "", "good golly miss molly!", $count);
echo
$count; // 2
?>

注: 本函数可安全用于二进制对象。

注: As of PHP 5.0.0 the number of matched and replaced needles (search) will be returned in count which is passed by reference. Prior to PHP 5.0.0 this parameter is not available.

See also str_ireplace(), substr_replace(), ereg_replace(), preg_replace(), and strtr().


add a note add a note User Contributed Notes
mcdaddy at godaddy dot com
03-Nov-2006 06:23
Take the following code:

$x = "Test@DATA@Test";
echo str_replace("@DATA@", "Test@DATA@Test", $x);

At first glance, one might think this could cause an infinite loop (continuous expansion).  Thankfully this only expands to:

TestTest@DATA@TestTest

Of course, the following WILL cause an infinite loop (and possibly run the system out of memory):

$x = "Test@DATA@Test";
$Count = 1;
while ($Count)
{
  $x = str_replace("@DATA@", "Test@DATA@Test", $x, $Count);
}
davidwhthomas at gmail dot com
24-Oct-2006 10:03
Just an update to Dimitri's code:

Replace Once:

I found this one worked best for me:

function replaceOnce($search, $replace, $content){

   $pos = strpos($content, $search);
   if ($pos === false) { return $content; }
   else { return substr($content, 0, $pos) . $replace . substr($content, $pos+strlen($search)); }

}

cheers,

DT
ahmad at infinity-medias dot com
07-Oct-2006 08:58
an enhanced version of Dmitry Fedotov's function that can handle arrays as input and output arguments ...

<?
$string
= "test1 test2 test3 test4";
echo
str_replace_once('test', 'testing', $string);
// testing1 test2 test3 test4

$string = ".NET sucks, Java sucks, PHP sucks"; // that doesn't sound right ... lets fix it!
echo str_replace_once("sucks", array("is stupid", "is ugly", "rules"), $string);
// .NET is is stupid, Java is ugly, PHP rules

function str_replace_once($search, $replace, $subject, &$offset = 0) {
   if (
is_array($search)) {
       if (
is_array($replace)) {
           foreach (
$search as $x => $value) $subject = str_replace_once($value, $replace[$x], $subject, $offset);
       } else {
           foreach (
$search as $value) $subject = str_replace_once($value, $replace, $subject, $offset);
       }
   } else {
       if (
is_array($replace)) {
           foreach (
$replace as $value) $subject = str_replace_once($search, $value, $subject, $offset);
       } else {
          
$pos = strpos($subject, $search, $offset);
           if (
$pos !== false) {
              
$offset = $pos+strlen($search);
              
$subject = substr($subject, 0, $pos) . $replace . substr($subject, $offset);
           }
       }
   }
  
   return
$subject;
}
?>
Will
22-Sep-2006 01:42
re: Fatidik's function
[!!EDITOR'S NOTE - referenced note removed!!]

No need to write a new function when the following gives the same result:

str_replace(array("\r", "\n"), "", $string)
ae at instinctive dot de
11-Sep-2006 10:22
CAUTION: This function will NOT do what you expect in many cases when you use arrays as both search and replace parameters. I found this out the hard way in a production website...

Consider the following code:

$a = "abcd";
$a = str_replace(array("a", "b", "c", "d"), array("albert ", "belinda ", "charlie ", "diana "), $a);
echo $a;

You would expect it to output "albert belinda charlie diana ", but it outputs:

"albelindiana a ert belindiana a charlie diana "

str_replace() simply executes itself for each array element, using the *already modified* string as input. This should be clearly noted in the manual.
Dmitry Fedotov box at neting dot ru
17-Aug-2006 12:44
This function replase in string

<?php
function ReplaceOne($in, $out, $content){
   if (
$pos = strpos($content, $in)){
       return
substr($content, 0, $pos) . $out . substr($content, $pos+strlen($in));
   } else {
       return
$content;
   }
}

$string = "TEXT bla bla bla TEXT bla bla TEXT";

echo
str_replace("TEXT", "1", $string); // 1 bla bla bla 1 bla bla 1

$content = ReplaceOne("TEXT", "1", $content); // 1 bla bla bla TEXT bla bla TEXT
$content = ReplaceOne("TEXT", "2", $content); // 1 bla bla bla 2 bla bla TEXT
$content = ReplaceOne("TEXT", "3", $content); // 1 bla bla bla 2 bla bla 3

// etc...

?>
webmaster at unitedscripters dot com
30-Jul-2006 09: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.
heavyraptor
29-Jul-2006 05:11
I had some problems with the function "remove_accents" by joaquin at metaltoad dot com. The problem was that it changed every encoded char, even encoded chars like &gt; (output was g, because the first char after the & is taken).
I changed it a little bit, it works fine now.

<?php
function replace_accents($str) {
 
$str = htmlentities($str);
 
$str = preg_replace('/&([a-zA-Z])(uml|acute|grave|circ|tilde);/','$1',$str);
  return
html_entity_decode($str);
}
?>

Example:
<?php
$str
= "    Text &%*'\\" <>";
$str = replace_accents($str);
echo $str; // prints "
aou AOU aee AEE Text &%*'" <>"
?>

Have fun
TLG
08-Jul-2006 03:53
About xinobit's function -> what if $search, $replace or/and $subject are arrays?.. ;)
I supplemented the code to support that possibility but the result was a bit heavy... and slow!
preg_replace() is about 5 times faster! :) (more or less depending on the length of $subject)

So, a little example of function:

<?php

function str_replace_limit($search, $replace, $subject, $limit=-1) {
  
// constructing mask(s)...
  
if (is_array($search)) {
       foreach (
$search as $k=>$v) {
          
$search[$k] = '`' . preg_quote($search[$k],'`') . '`';
       }
   }
   else {
      
$search = '`' . preg_quote($search,'`') . '`';
   }
  
// replacement
  
return preg_replace($search, $replace, $subject, $limit);
}

?>

(of course you could insert a "&$count" argument for PHP >= 5.1.0)
admc AT admc DOT hu
06-Jul-2006 01:12
Inspired by the first official example here, that gives "<body text='black'>", I wrote a little function that replaces strings using a "dictionary":

function sablongep($sablon, $helyettesites) {
   foreach ($helyettesites as $nev => $adat)
       $sablon=str_replace("%$nev%", $adat, $sablon);
  
   return $sablon;
}

Example:

sablongep("We have a lot of fruits: %fruits%, and some vegetables: %vegetables%.",
   array(    "fruits" => "apple, banana, cherry",
       "vegetables" => "carrot, cabbage"));

I admit that this example is not as funny as the others in the manual...
xinobit at gmail dot com
08-Jun-2006 11:59
Here's a function that will replace many times as the last argument ask.

<?

function str_replace_count($search,$replace,$subject,$times) {

  
$subject_original=$subject;
  
  
$len=strlen($search);   
  
$pos=0;
   for (
$i=1;$i<=$times;$i++) {
      
$pos=strpos($subject,$search,$pos);
      
       if(
$pos!==false) {               
          
$subject=substr($subject_original,0,$pos);
          
$subject.=$replace;
          
$subject.=substr($subject_original,$pos+$len);
          
$subject_original=$subject;
       } else {
           break;
       }
   }
  
   return(
$subject);

}

$w="abracadabra";

print
str_replace_count("abra","----",$w,2);

?>
03-Apr-2006 10:57
Here's a function I put together from pieces other folks wrote. First, it replaces all MS Word smart quotes, EM dashes and EN dashes with their ASCII equivalents, then it goes through and deletes any non-ASCII characters (such as the 1/4 character).  The function was written with backwards-compatibility in mind, not performance. It worked successfully in PHP Version 4.2.3, but not in Version 4.2.2. Hopefully it'll help out someone:

function all_ascii( $stringIn ){
   $final = '';
   $search = array(chr(145),chr(146),chr(147),chr(148),chr(150),chr(151));
   $replace = array("'","'",'"','"','-','-');

   $hold = str_replace($search[0],$replace[0],$stringIn);
   $hold = str_replace($search[1],$replace[1],$hold);
   $hold = str_replace($search[2],$replace[2],$hold);
   $hold = str_replace($search[3],$replace[3],$hold);
   $hold = str_replace($search[4],$replace[4],$hold);
   $hold = str_replace($search[5],$replace[5],$hold);

   if(!function_exists('str_split')){
       function str_split($string,$split_length=1){
           $count = strlen($string);
           if($split_length < 1){
               return false;
           } elseif($split_length > $count){
               return array($string);
           } else {
               $num = (int)ceil($count/$split_length);
               $ret = array();
               for($i=0;$i<$num;$i++){
                   $ret[] = substr($string,$i*$split_length,$split_length);
               }
               return $ret;
           }
       }
   }

   $holdarr = str_split($hold);
   foreach ($holdarr as $val) {
       if (ord($val) < 128) $final .= $val;
   }
   return $final;
}

Example usage:  echo all_ascii( $myString );
matt wheaton
30-Mar-2006 11: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);
?>
vlatko dot surlan at RMVME gmail dot com
31-Jan-2006 01:57
Suggested code has some drawbacks in the context of many replacement pairs (i am not suggesting that mine has none). The example code you provided:

<?php
return str_replace(
  array(
'&#262;', '&#263;', '&#264;', [...]),
  array(
'&#262;', '&#263;', '&#264;', [...]),
 
strtoupper($string)
 ) ;
?>

relies on the fact that visual identation is provided by all replacement elements beeing of the same width, which is hardly ever true in the real world (please correct me if I'm wrong). Another nasty feature is that this code extends to the right with addition of new elements while the solution provided in the earlier post extends in the driection of the natural flow of code, thus, retaining correct code width for all cases. Perhaps you have ommited the fact that I specifically intended suggested code format for cases with many replacement pairs indicated with /* many lines here */ in the previous post?
admin at sellchain dot com
31-Oct-2005 07:55
<?

# This is a complete profanity filter. I couldn't get any of the preg_replace statements working, so I made one that is CASE INSENSITIVE, SPACE INSENSITIVE too.

$original="This contains curseword, curse_word1, cursewor_d2, cursewo_rd3, and a bunch of other text...";

echo
"Before: $original<br><br>";
$original=RemoveCurseWords($original);
echo
"After: $original<br><br>";

function
RemoveCurseWords($original) {

$patterns[0] = 'curseword';
$patterns[1] = 'curse_word1';
$patterns[2] = 'cursewor_d2';
$patterns[3] = 'cursewo_rd3';

$finalremove=$original;
$piece_front="";
$piece_back="";
$piece_replace="***";

   for (
$x=0; $x < count($patterns); $x++) {

  
$safety=0;
# Prevents infinity loops if you accidentally put in replacements that match your patterns. it could happen! :)
# The saftey could cause issues if you are replacing more than 100,000 occurrences in a string, so remove it if you trust it.

      
while(strstr(strtolower($finalremove),strtolower($patterns[$x]))) {
      
# find & remove all occurrence
      
      
$safety=$safety+1;
       if (
$safety >= 100000) { break; }

      
$occ=strpos(strtolower($finalremove),strtolower($patterns[$x]));
      
$piece_front=substr($finalremove,0,$occ);
      
$piece_back=substr($finalremove,($occ+strlen($patterns[$x])));
      
$finalremove=$piece_front . $piece_replace . $piece_back;
       }
# while
      
  
} # for

return $finalremove;

}
# function RemoveCurseWords
tjomi4 at yeap dot lv
18-Oct-2005 10:46
<?php
function utf8_str_replace($s,$r,$str){
# utf8 str_replace
# www.yeap.lv
 
if(!is_array($s)){
 
$s = '!'.preg_quote($s,'!').'!u';
  }else{
  foreach (
$s as $k => $v) {
  
$s[$k] = '!'.preg_quote($v).'!u';
  }
 }
return
preg_replace($s,$r,$str);
}
?>
spectrereturns at creaturestoke dot com
23-May-2005 05:53
This is a little function I wrote replaces substrings in a string with different values. If there are more instances of $search in $string then there are elements in $replace, it will start over.

<?php
 
function replace_different($search,$replace,$string) {
  
$occs = substr_count($string,$search);
  
$last = 0;
  
$cur = 0;
  
$data = '';
   for (
$i=0;$i<$occs;$i++) {
    
$find = strpos($string,$search,$last);
    
$data .= substr($string,$last,$find-$last).$replace[$cur];
    
$last = $find+strlen($search);
     if (++
$cur == count($replace)) {
      
$cur = 0;
     }
   }
   return
$data.substr($string,$last);
  }
?>

Example:
<?php
$string
= '`atext`,`btext`';
echo
replace_different('`',array('0~`','1~`'),$string);
?>
Will return:

0~`atext1~`,0~`btext1~`
will at 4lx dot net
13-Apr-2005 09:06
This function is an example of replacing month numbers with the actual textual value. 

<?php
function createMonths($month_start,$month_end) {
  
$month = array("1", "2", "3", "4", "5", "6",
    
"7", "8", "9", "10", "11", "12");
  
$month_replace = array("January","February","March","April","May","June",
  
"July","August","September","October","November", "December");
  
$x_end = $month_end + 1;
  
// Add one to the value of the end month
  
for ($x = $month_start; $x < $x_end; $x++) {
      
$new_months .= $x.",";
      
// Count from the begin month to the end month
      
}
      
$new_months = substr($new_months,0,-1);
      
// Cut the last comma off the end month
      
$newmonth = explode(",", $new_months);
      
// Place each int month into an array
      
$newsmonth = str_replace($month,$month_replace,$newmonth);
      
// Replace the int month with a textual string
      
var_dump ($newsmonth);
      
// Dump the data
  
}
createMonths(1,3);
/* Will print array(3)
{ [0]=> string(7) "January" [1]=> string(8) "February" [2]=> string(5) "March" } */
?>
a_baboshin at mail dot ru
04-Apr-2005 10:00
I wrote 2 function's file_replace() and dir_replace() with str_replace() signature

   function file_replace ($search, $replace, $filename) {
       if (file_exists($filename)) {
           $cnt = file_get_contents($filename);
           if (strstr($cnt, $search)) {
               $cnt = str_replace($search, $replace, $cnt);
               return file_put_contents($filename, $cnt);
           }
           return true;
       }
       return false;
   }
  
   function dir_replace ($search, $replace, $dirname, $recursive = true) {
       $dir = opendir($dirname);
       while ($file = readdir($dir)) {
           if ($file != '.' && $file != '..') {
               if (is_dir($dirname.'/'.$file)) {
                   if ($recursive) {
                       dir_replace($search, $replace, $dirname.'/'.$file);
                   }
               } else {
                   file_replace($search, $replace, $dirname.'/'.$file);
               }
           }
       }
   }

usage ('search', 'replace', '/usr/home/root');
joaquin at metaltoad dot com
25-Mar-2005 08:04
This is an another accent remover which converts foreign characters to their English equivilent. It converts any  character's to their HTML value and then uses preg_replace to find the desired value.  The function is based on a earlier entry: replace_accents.

function remove_accents( $string )
{
   $string = htmlentities($string);
   return preg_replace("/&([a-z])[a-z]+;/i","$1",$string);
}

example:

$string = "C";
echo remove_accents( $string );

// will output: eecyCECA
hermes at andycostell dot com
12-Dec-2004 03: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!
aidan at php dot net
27-Jun-2004 01:53
Here is a simple function for highlighting a needle in text. It is careful to not replace text in HTML tags (unless specified).

http://aidan.dotgeek.org/lib/?file=function.str_highlight.php


Example: The google method of highlighting

<?php
$text
= "Here is some text with a search term";
$needle = "search term";
echo
str_highlight($text, $needle);
?>

Output:
Here is some text with a <strong>search term</strong>
aidan at php dot net
27-Jun-2004 01:07
If you would like to convert tabs to spaces, you could use the code:

<?php
str_replace
("\t", "    ", $text);
?>

However, sometimes this is not good enough. To be technically correct, a tab is not 4 spaces, a tab shifts the text to the next predefined column. Usually these predefined columns occur every 4 spaces from the start of the line.

If you want to convert tabs to spaces while ensuring consistant formatting, try this function...

http://aidan.dotgeek.org/lib/?file=function.tab2space.php
rylas at mudmirror dot com
04-Jun-2004 06:48
An easy way to convert email addresses to the PHP.net comment-style email addresses:

<?
$email
= "john@doe.org";
$search = array('@', '.');
$replace = array(" at ", " dot ");
$result = str_replace($search, $replace, $email);
?>

Outputs:
john at doe dot org
jr at adslate dot com
03-Jun-2004 08:52
When the first argument to str_replace() is an array, the elements are checked in increasing order of array index, as one would expect.

For example,

str_replace (array ('ABC', 'BC'), array ('E', 'F'), 'ABC')
returns 'E';

str_replace (array ('BC', 'ABC'), array ('E', 'F'), 'ABC')
returns 'AE'.
Darren Gates - http://www.tufat.com
15-Mar-2004 05:22
Here's a version of str_replace which ignores differences in spacing (like tab, carriage return, line feed, etc.) in the two input strings.

Courtesy of http://www.tufat.com (Darren's Script Archive).

<?php
function str_rep($srcfor,$chwith,$mystr)
{
   if(
strlen($mystr) == 0)
       return
"";

  
$tok  = strtok($srcfor," \n\t\r");
  
$strsrc = array();
  
$idxsrc = array();
  
$i = 0;
   while(
$tok)
   {
      
$strsrc[$i] = $tok;
      
$pos = strpos($srcfor,$tok);
      
$idxsrc[$i]=$pos;
      
$tok = strtok(" \n\r\t");
      
$i++;
   }

  
$tok2  = strtok($mystr," \n\t\r");
  
$str = array();
  
$idx = array();
  
$j = 0;

   while(
$tok2)
   {
      
$str[$j] = $tok2;
      
$pos = strpos($mystr,$tok2);
      
$idx[$j]=$pos;
      
$tok2 = strtok(" \n\r\t");
      
$j++;
   }

   for(
$m=0;$m<$j;$m++)
   {
       if(
strcasecmp($strsrc[0] , $str[$m]) == 0)
       {
           for(
$l=1;$l<$i;$l++)
           {
               if(
strcasecmp($strsrc[$l],$str[$m+$l]) != 0)
                   break;
           }
          
$l--;
           if((
$l+1) == $i)
           {

              
$new_str=substr($mystr,0,$idx[$m]);
              
$new_str .= $chwith;

              
$index = $idx[$m+$l]+strlen($str[$l+$m]);
              
$len = strlen($mystr)-$index;

               if(
$len > 0)
                  
$new_str .= str_rep($srcfor,$chwith,substr($mystr,$index,$len));

               return
$new_str;
               break;
           }

       }
   }

   return
$mystr;
}
?>
unusedacct at no$p at m dot comcast dot net
20-Feb-2004 01:45
For those who haven't yet updated to PHP 5 yet, here is a quick function to do regular str_replace on a string [not arrays] only a certain number of times:

<?php

function str_replace_count($find,$replace,$subject,$count)
{
  
$subjectnew = $subject;
  
$pos = strpos($subject,$find);
   if (
$pos !== FALSE)
   {
     while (
$pos !== FALSE)
     {
        
$nC = $nC + 1;
        
$temp = substr($subjectnew,$pos+strlen($find));
        
$subjectnew = substr($subjectnew,0,$pos) . $replace . $temp;
         if (
$nC >= $count)
         {
           break;
         }
        
$pos = strpos($subjectnew,$find);
     }
// closes the while loop
  
} // closes the if
  
return $subjectnew;
}

$stuff = "a b a b a b a b a";

print
$stuff . " -- the old string<br>\n";

print
str_replace_count("a ","c ",$stuff,4) . " -- the new string<br>\n";
// will output c b c b c b c b a -- the new string

?>

Hope this helps.
xavier paz (xpaz at matadracs dot com)
31-Dec-2003 02:39
If both the search and replace params are arrays, str_replace() will apply the substitutions incrementally, it is, it will try the first substitution, then the second using the result from the first one, and so on. It may be OK, or it may be a problem if you only want to change the original text.

For example, consider this code:
<?php
$search
= array("one", "two", "three");
$replace = array("two", "three", "one");
$subject = "one two three";
echo
str_replace($search, $replace, $subject). "<br>";
// echoes "one one one"
?>

This function makes the substitutions only to the original text.

<?php
/**
 * same as str_replace (array, array, string), but changing only the text in the
 * original string
 * $search and $replace are arrays of strings, $subject is a string
 */
function str_replace_clean($search, $replace, $subject) {
   if (!
is_array($search) or !is_array($replace) or !is_string($subject)) return $subject;
   while (
count($search)) {
      
// get current terms, reduce the arrays for the next iteration
      
$search_text = array_shift($search);
      
$replace_text = array_shift($replace);
      
// check if the substring is present
      
$pos = strpos($subject, $search_text);
       if (
is_int($pos)) {
          
// match found - break in pieces
          
$pieces = explode($search_text, $subject);
           if (
count($search)) { // only if there are more substitutions to do
               // make next substitutions in every piece of text between matches
              
foreach ($pieces as $k => $v) {
                   if (
strlen($v)) $pieces[$k] = str_replace_clean($search, $replace, $v);
               }
           }
          
$subject = join($replace_text, $pieces);
           break;
       }
   }
   return
$subject;
}
?>

To test:
<?php
echo str_replace_clean($search, $replace, $subject);
// echoes "two three one"
?>

-- Xavier
thewolf at pixelcarnage dot com
23-Oct-2003 10:45
I also wanted to replace rude words in a pice of text, I had  str_replace replacing the word with *** but then I had a thought, what if I could replace these bad words and words also very similar? In the end I wrote this code, it uses two functions, one to check if the similarity between two words is high enough to qualify for filtering out and one to do the actual replacing (modified from my word_replace function):

<?php
$text
= 'This is some text with a baword in it.';
echo
similar_str_replace('badword', '*******', $text, 80);
  
function
is_similar($one, $two, $similarity) {
  
similar_text($one, $two, $percent);
   return
$percent >= $similarity ? true : false;
}

/**
 * Written by Rowan Lewis of PixelCarnage.com
 * $search(string), the string to be searched for
 * $replace(string), the string to replace $search
 * $subject(string), the string to be searched in
 * $similarity(int), how similar the two words must be
 */
function similar_str_replace($search, $replace, $subject, $similarity = 85) {
   return
preg_replace('/[a-zA-Z]+/e', 'is_similar(\'\0\', \'' . $search . '\', \'' . $similarity . '\') ? \'' . $replace . '\': \'\0\';', $subject);
}
?>

Just wack that into a php file, its ready for testing!

Hope someone uses it, and perhaps improves it somehow.
thewolf at pixelcarnage dot com
23-Oct-2003 10:38
I got sick of trying to replace just a word, so I decided I would write my own string replacement code. When that code because far to big and a little faulty I decided to use a simple preg_replace:

<?php
/**
 * Written by Rowan Lewis of PixelCarnage.com
 * $search(string), the string to be searched for
 * $replace(string), the string to replace $search
 * $subject(string), the string to be searched in
 */
function word_replace($search, $replace, $subject) {
   return
preg_replace('/[a-zA-Z]+/e', '\'\0\' == \'' . $search . '\' ? \'' . $replace . '\': \'\0\';', $subject);
}
?>

I hope that this code helpes someone!
David Gimeno i Ayuso (info at sima-pc dot com)
25-Aug-2003 09: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".
imho at auspantheon dot com
27-Jun-2003 07: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('&', '&amp;', $line);
   }
}
?>

The same technique could also be used in conjuntion with htmlmspecialchars or htmlentities.
dbergeron [at] clincab [dot] com
26-Jun-2003 02:08
here is a function to highlight a part of a string. Unlike str_replace, it is both case insensitive, and maintains the case of the highlighted text.

<?php
function highlight($x,$var) {//$x is the string, $var is the text to be highlighted
  
if ($var != "") {
      
$xtemp = "";
      
$i=0;
       while(
$i<strlen($x)){
           if(((
$i + strlen($var)) <= strlen($x)) && (strcasecmp($var, substr($x, $i, strlen($var))) == 0)) {
//this version bolds the text. you can replace the html tags with whatever you like.
                  
$xtemp .= "<b>" . substr($x, $i , strlen($var)) . "</b>";
                  
$i += strlen($var);
           }
           else {
              
$xtemp .= $x{$i};
              
$i++;
           }
       }
      
$x = $xtemp;
   }
   return
$x;
}
?>

Example:
<?php
$string
= "AaBbCcDd";
$string = highlight($string, "bc");
echo
$string; //AaB<b>bC</b>cDd
?>
13-Jun-2003 06:59
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.
chirag at chime dot tv
23-Mar-2003 04:35
All the Google-like highlight functions above mess up when the needle is within the url too. getHTMLHighlight function below works fine:

<?php
function getHTMLHighlight($needle, $haystack, $hlS, $hlE)
{
  
$parts = explode(">", $haystack);
   foreach(
$parts as $key=>$part)
   {
    
$pL = "";
      
$pR = "";

     if((
$pos = strpos($part, "<")) === false)
      
$pL = $part;
     elseif(
$pos > 0)
     {
      
$pL = substr($part, 0, $pos);
      
$pR = substr($part, $pos, strlen($part));
     }
     if(
$pL != "")
      
$parts[$key] = preg_replace('|\b('.quotemeta($needle).')\b|iU', $hlS.'\\1'.$hlE, $pL) . $pR;
   }
   return(
implode(">", $parts));
}
?>

Usage:

getHTMLHighlight($needle, $haystack, "<b style=\"background-color:#FF3145\">", "</b>");
mv@anywhere dot br
13-Feb-2003 10:03
how to remove accents from text

<?php
function accents($text) {
   global
$export;
  
$search  = array ('', '', '', '', '', '', '', '', '', '', '', '', '');
  
$replace = array ('c', 'a', 'e', 'i', 'o', 'u', 'a', 'o', 'a', 'e', 'i', 'o', 'u');
  
$export    = str_replace($search, $replace, $text);
   return
$export;
}

accents("Carnaval  s no Brasil");
?>
rit at NOSPAMchatol dot com
07-Jan-2003 08: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!
Shane43 at aol dot com
17-Oct-2002 10:12
Keep in mind that if you are trying to remove all the newlines (\n) from a fields that was submitted in a form, you may need look for \r\n instead:

If this doesn't work:
$text=str_replace ("\n", " ", $text);

then try this:
$text=str_replace ("\r\n", " ", $text);
art at zollerwagner dot com
10-Oct-2002 06: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);
?>
gwkeeper at mmhk dot cz
01-Oct-2002 02:47
Hi, if You want to use case insensitive replacement with support eastern languages e.g. czech special chars try this:

<?php
$text
= eregi_replace ( (sql_regcase($searched_text)), "<span class=\"Marked_1\" >\\0</span>", $text );
?>

without sql_regcase it did not found some special eastern chars
paul at atomicrevs dot net
28-Aug-2002 10:29
I made this to parse values returned in a form, but to preserve formatting so that it doesn't get removed in the "remove anything but alphanumeric" line...  Probably not elegant, but it works.

<?php
foreach ($_POST as $key => $val)
  {
  
$val = preg_replace("(\r\n|\n|\r)", "#", $val);
  
$val = preg_replace("/[^0-9a-z -#]/i",'', $val); // strip anything we don't want
  
$val = str_replace("#", "*", $val); // * Put a p or br here.
  
$_POST[$key] = $val;
  }
?>
unleadedis at optusnet dot com dot au dot nospam
12-Aug-2002 03:48
The problem is that str_replace seems to call the replace even though there may not be a replacement.

This is a problem in that in my parsing script when it finds a certain tag it calls a function, this function does a few SQL queries. It has been noticed that doing a str_replace on a page that contains no 'tag' that I am searching for, the function is called anyway!!!

To get around this I have to do a str_pos to see if it exists then call str_replace.

eg,
<?php
// Breadcrumb trail (same as per sitemap)
$bc_pos = strpos($string,"[[breadcrumbtrail]]");
if (
$bc_pos || is_numeric($bc_pos)) { // true ? then exectue!
  
$string = str_replace ("[[breadcrumbtrail]]",
        
generate_breadcrumb($nodedata_arr, $db), $string);
}
?>
tapken at engter dot de
25-May-2002 06:34
If you want to replace only the first occurence of a string you can use this function:

<?php
function str_replace_once($needle, $replace, $haystack) {
  
// Looks for the first occurence of $needle in $haystack
   // and replaces it with $replace.
  
$pos = strpos($haystack, $needle);
   if (
$pos === false) {
      
// Nothing found
      
return $haystack;
   }
   return
substr_replace($haystack, $replace, $pos, strlen($needle));
}
?>
dpardo at fia dot es
04-Apr-2002 04:03
If you are working with spanish characters and you are using accent (marks,quotes) you have to use something similar to this

$q = str_replace("&aacute;", "a", $q);