note 43621 rejected from function.str-replace by aidan
| From: | aidan@php.net | Date: | Sat, 03 Jul 2004 07:04:40 +0000 |
| Subject: | note 43621 rejected from function.str-replace by aidan | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-72357@lists.php.net to get a copy of this message | ||
Note Submitter: Jeroen - http://jeroen.all-stars.nl
----
If you use function str_replace with arrays, it will apply the substitutions incrementally, that is,
it will try the first substitution, then the second using the result from the first one, and so on.
That may be okay, or it may be a problem if you only want to change the original text.
For example, consider this code:
$search = array("one", "two", "three");
$replace = array("two", "three", "one");
$subject = "one two three";
str_replace($search, $replace, $subject) returns "one one one".
Function str_replace_clean (see below) makes the substitutions only to the original text. For the
above example, str_replace_clean($search, $replace, $subject) would return "two three
one".
The basis for this function comes from the contribution by Xavier Paz on www.php.net/str_replace
(30-Dec-2003).
I modified it so that all parameters can be arrays or strings, and I added an option for
case-sensitive comparison or not (standard function str_replace() always compares case-sensitive).
The code of the function is given below. You can also download it from http://jeroen.all-stars.nl/php.php
You will also find more information about the function there, a class with the function for
object-oriënted coding, and testprograms to compare function str_replace_clean with standard
function str_replace.
<?php
function str_replace_clean($search_in, $replace_in, $subject_in, $cs=true, $subject_out=array())
{
if ($cs!==true and $cs!==false) return $subject_in;
$search=$search_text=$replace=$replace_text=array();
if (is_array($search_in)) {
$search = $search_in;
}
elseif (is_string($search_in)) {
$search[] = $search_in; //array_push doesn't work here
}
if (is_array($replace_in)) {
$replace = $replace_in;
}
elseif (is_string($replace_in)) {
//make an array with the length of array $search
foreach ($search as $dummy)
{
$replace[] = $replace_in; //array_push doesn't work here
}
}
if (is_array($subject_in))
{
foreach ($subject_in as $subject)
{
$resultsubject = do_while_for_str_replace_clean($search, $replace, $subject, $cs, $subject_out);
$subject_out[] = $resultsubject; //array_push doesn't work here
}
return $subject_out;
}
elseif (is_string($subject_in))
{
$subject=$subject_in;
$resultsubject = do_while_for_str_replace_clean($search, $replace, $subject, $cs, $subject_out);
return $resultsubject;
}
}
function do_while_for_str_replace_clean($search, $replace, $subject, $cs, $subject_out)
{
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
if ($cs===true)
{
$pos = strpos($subject, $search_text);
$break=$search_text;
}
else
{
$pos = strpos(strtolower($subject), strtolower($search_text));
if (is_int($pos))
{
//replace all matches with their lowercase values for later explode()
$len=strlen($search_text);
$subject_len=strlen($subject);
for ($pos2=$pos; ($pos2+$len)<=$subject_len ; $pos2=$newpos)
{
$subject=substr($subject,0,$pos2)
.strtolower($search_text)
.substr($subject,$pos2+$len);
$newpos = strpos(strtolower($subject), strtolower($search_text),$pos2+$len);
if (!is_int($newpos)) break;
}
}
$break=strtolower($search_text);
}
if (is_int($pos))
{
// match found - break in pieces
$pieces = explode($break, $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, $cs, $subject_out);
}
}
$subject = join($replace_text, $pieces);
break;
}
} //end while
return $subject;
}
?>