Imagine the following inputs and the desired output after str_replace_except_last($replace_except_last,$replacement,$text)
:
func(".","",12.833331.3198912.980289012.92) => 128333313198912980289012.92
func(".","",31.0) => 31.0
func(".","",8) => 8
func(".","",9190.1.1.1....1.1.....1) => 919011111.1
func(".","",98909090....) => 98909090.
func("beer","","My beer is the best beer.") => My is the best beer.
func("it","fit,"Is it really it or is it not?") => Is fit really fit or is it not?
Want to perform the simple task of removing every occurrence of a character or substring but NOT the last occurrence. Basically this is what str_replace
does, however it replaces any occurrence.
Hint: Made some experiments with substr_count
however I did not find how to replace ocurrence number X in a string easily?
I think this will be the most efficient/simple solution (however I didn't run it though some run-time test).
function str_replace_except_last($needle, $replace, $text) {
if ($last_pos = strrpos($text, $needle)) {
$text = str_replace($needle, $replace, substr($text, 0, $last_pos)) . substr($text, $last_pos);
}
return $text;
}
Since the question was also related to efficiency, I decided to test the two versions (mine and the one offered by @Don'tPanic, which is based on arrays).
First - Let me just say that premature optimization is the root of all evil
Now that we are done with that we can move next :)
I decided to create a random string of 10M chars, the string will also contain .
(which will be our needle).
I run the two functions 1000 times on same string and checked the average time it took each function to run.
I also checked how much memory each function took to work.
Here are the results:
Here is the complete code (if you want to run it yourself):
$ITERATIONS = 1000;
function generateRandomString($length = 10) {
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ. ';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
return $randomString;
}
function func_str($needle, $replace, $text) {
$m1 = memory_get_usage();
if ($last_pos = strrpos($text, $needle)) {
$text = str_replace($needle, $replace, substr($text, 0, $last_pos)) . substr($text, $last_pos);
}
$m2 = memory_get_usage();
//echo "memory diff ". ($m2-$m1) ."\n";
return $text;
}
function func_arr($needle, $replace, $text) {
$m1 = memory_get_usage();
$array = explode($replace, $text, substr_count($text, $replace));
$text = implode($replacement, $array);
$m2 = memory_get_usage();
//echo "memory diff ". ($m2-$m1) ."\n";
return $text;
}
$m1 = memory_get_usage();
$s = microtime(true);
$str1 = generateRandomString(10000000);
$e = microtime(true);
echo "create took ". ($e-$s) ." seconds\n";
echo "Number of occurances: " . substr_count($str1, '.') . "\n";
$s = microtime(true);
for ($i = 0; $i < $ITERATIONS; $i++) {
func_str(".","",$str1);
}
$e = microtime(true);
echo "remove took ". ($e-$s) ." seconds, avg: ". ($e-$s)/$ITERATIONS ."\n";
$s = microtime(true);
for ($i = 0; $i < $ITERATIONS; $i++) {
func_arr(".","",$str1);
}
$e = microtime(true);
echo "remove took ". ($e-$s) ." seconds, avg: ". ($e-$s)/$ITERATIONS ."\n";
(I commented out the output of the memory usage inside the functions, if you want it you can remove the comment).
Split the main string on the string to replace (except for the last piece), then join it back together with the replacement.
function str_replace_except_last($replace, $replacement, $text) {
$array = explode($replace, $text, substr_count($text, $replace));
return implode($replacement, $array);
}
You could use preg_replace to remove every occurrence except the last. The regex does a look ahead and only replaces if the pattern also exists later in the string.
$str = '66.768.876876.8.7876';
$pattern = '.';
echo(str_replace_except_last($pattern, '', $str));
function str_replace_except_last($replace_except_last, $replacement, $text)
{
$pattern = preg_quote($replace_except_last);
return preg_replace('/' . $pattern . '(?=[^' . $pattern . ']*' . $pattern . '[^' . $pattern . ']*)/', $replacement, $text);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With