note 87489 deleted from function.str-replace by philip
| From: | philip@php.net | Date: | Wed, 07 Oct 2009 15:46:48 +0000 |
| Subject: | note 87489 deleted from function.str-replace by philip | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-161474@lists.php.net to get a copy of this message | ||
Note Submitter: gabriel dot totoliciu at ddnet dot ro
----
As 'max at efoxdesigns dot com' said, when you try to replace a string that occurs in the
$search array after the same character occurs in the $replace character, you don't usually get
what you want.
examples:
<?php
$search=array("beer", "graffiti", "programming");
$replace=array("graffiti", "motorcycles", "chips");
$string="I like beer, graffiti and programming.";
var_dump(str_replace($search, $replace, $string));
// you would expect to see:
// string(39) "I like graffiti, motorcycles and chips."
// well.. what you actually see is:
// string(42) "I like motorcycles, motorcycles and chips."
?>
I've made a function (stru_replace) that replaces everything correctly. It has some downsides,
as it does not implement all the functionality of str_replace:
<?php
$search=array("beer", "graffiti", "programming");
$replace=array("graffiti", "motorcycles", "chips");
$string="I like beer, graffiti and programming.";
var_dump(str_replace($search, $replace, $string));
//string(39) "I like graffiti, motorcycles and chips."
?>
I'm sure that the functions can be improved. Anyway, I guess they are a bit useful :D
<?php
//returns the key of the minimum value within the array
function minkey($array)
{
$first=true;
$mkey=false;
$mvalue=false;
foreach($array as $key=>$value)
{
if (is_numeric($value))
{
if ($mvalue>$value || $first)
{
$mvalue=$value;
$mkey=$key;
if ($first) $first=false;
}
}
}
return $mkey;
}
//returns the key and the position of the first needle found withing the (string)haystack
function strposfirst($haystack, $needles, $currentpos=0)
{
$positions=array();
foreach($needles as $key=>$value)
$positions[$key]=strpos($haystack,$value,$currentpos);
$minkey=minkey($positions);
if ($minkey===false) return array(false, false);
return array($minkey, $positions[$minkey]);
}
//third parameter must be a string
function stru_replace($search, $replace, $string)
{
$newString="";
// the function only implements functionality for the $search and $replace parameters
// as arrays that have the same ammount of elements
if (is_array($search) && is_array($replace))
{
if (count($search)!=count($replace))
throw new ErrorException("The \$search and \$replace parameters must have the same number of
elements");
$oCPos=0; // current position inside old string
$done=false; // determines when we searched all the string
while(!$done)
{
//get the key and position of the first found element
list($key, $position)=strposfirst($string, $search, $oCPos);
//if there is a found element, get concatenate the string before it, and replace the string
if ($position!==false)
{
// the string before the needle is concatenated in the new string
$newString.=substr($string, $oCPos, $position-$oCPos);
// the needle is replaced
$newString.=$replace[$key];
//add the with of the length of the string before the needle + the length of the new key
$oCPos+=$position-$oCPos+strlen($search[$key]);
}
//set the done flag when nothing is found (position is false)
else $done=true;
}
//concatenate the string after the last needle
$newString.=substr($string, $oCPos);
return $newString;
}
else return str_replace($search, $replace, $string);
}
?>
I hope this helps :)
If I'll change the functions, you'll find them here
http://pb.dev.ddnet.ro/phpLecture/issue1.php