Anyone know of a very fast way to replace the last occurrence of a string with another string in a string?
Note, the 开发者_开发百科last occurrence of the string might not be the last characters in the string.
Example:
$search = 'The';
$replace = 'A';
$subject = 'The Quick Brown Fox Jumps Over The Lazy Dog';
Expected Output:
The Quick Brown Fox Jumps Over A Lazy Dog
You can use this function:
function str_lreplace($search, $replace, $subject)
{
$pos = strrpos($subject, $search);
if($pos !== false)
{
$subject = substr_replace($subject, $replace, $pos, strlen($search));
}
return $subject;
}
Another 1-liner but without preg:
$subject = 'bourbon, scotch, beer';
$search = ',';
$replace = ', and';
echo strrev(implode(strrev($replace), explode(strrev($search), strrev($subject), 2))); //output: bourbon, scotch, and beer
$string = 'this is my world, not my world';
$find = 'world';
$replace = 'farm';
$result = preg_replace(strrev("/$find/"),strrev($replace),strrev($string),1);
echo strrev($result); //output: this is my world, not my farm
The following rather compact solution uses the PCRE positive lookahead assertion to match the last occurrence of the substring of interest, that is, an occurrence of the substring which is not followed by any other occurrences of the same substring. Thus the example replaces the last 'fox'
with 'dog'
.
$string = 'The quick brown fox, fox, fox jumps over the lazy fox!!!';
echo preg_replace('/(fox(?!.*fox))/', 'dog', $string);
OUTPUT:
The quick brown fox, fox, fox jumps over the lazy dog!!!
You could do this:
$str = 'Hello world';
$str = rtrim($str, 'world') . 'John';
Result is 'Hello John';
This is an ancient question, but why is everyone overlooking the simplest regexp-based solution? Normal regexp quantifiers are greedy, people! If you want to find the last instance of a pattern, just stick .*
in front of it. Here's how:
$text = "The quick brown fox, fox, fox, fox, jumps over etc.";
$fixed = preg_replace("((.*)fox)", "$1DUCK", $text);
print($fixed);
This will replace the last instance of "fox" to "DUCK", like it's supposed to, and print:
The quick brown fox, fox, fox, DUCK, jumps over etc.
This will also work:
function str_lreplace($search, $replace, $subject)
{
return preg_replace('~(.*)' . preg_quote($search, '~') . '(.*?)~', '$1' . $replace . '$2', $subject, 1);
}
UPDATE Slightly more concise version (http://ideone.com/B8i4o):
function str_lreplace($search, $replace, $subject)
{
return preg_replace('~(.*)' . preg_quote($search, '~') . '~', '$1' . $replace, $subject, 1);
}
$string = "picture_0007_value";
$findChar =strrpos($string,"_");
if($findChar !== FALSE) {
$string[$findChar]=".";
}
echo $string;
Apart from the mistakes in the code, Faruk Unal has the best anwser. One function does the trick.
You can use strrpos() to find last match.
$string = "picture_0007_value";
$findChar =strrpos($string,"_");
$string[$findChar]=".";
echo $string;
Output : picture_0007.value
Shorthand for accepted answer
function str_lreplace($search, $replace, $subject){
return is_numeric($pos=strrpos($subject,$search))?
substr_replace($subject,$replace,$pos,strlen($search)):$subject;
}
A short version:
$NewString = substr_replace($String,$Replacement,strrpos($String,$Replace),strlen($Replace));
While using regex is typically less performant than non-regex techniques, I do appreciate the control and flexibility that it affords.
In my snippet, I will set the pattern to be case-insensitive (\i
, although my sample input will not challenge this rule) and include word boundaries (\b
, although they were not explicitly called for).
I am also going to use the \K
metacharacter to reset the fullstring match so that no capture groups / backreferences are needed.
Code: (Demo)
$search = 'The';
$replace = 'A';
$subject = "The Quick Brown Fox Jumps Over The Lazy Dog's Thermos!";
echo preg_replace(
'/.*\K\b' . preg_quote($search, '/') . '\b/i',
$replace,
$subject
);
Output:
The Quick Brown Fox Jumps Over A Lazy Dog's Thermos!
# ^^^ ^ ^^^
# not replaced replaced not replaced
Without word boundaries: (Demo)
echo preg_replace(
'/.*\K' . preg_quote($search, '/') . '/i',
$replace,
$subject
);
Output:
The Quick Brown Fox Jumps Over The Lazy Dog's Armos!
# ^^^ ^^^ ^
# not replaced not replaced replaced
Below corrected zack's code (https://stackoverflow.com/a/11144999/9996503). Be careful with regular expressions! Consider this:
$string = 'Round brackets (parentheses) "()", square brackets "()"';
$find = '()';
$replace = '[]';
// Zack's code:
$result = preg_replace(strrev("/$find/"),strrev($replace),strrev($string),1);
var_dump($result); // Output: NULL
// Correct code:
$result = strrev(preg_replace('/'.preg_quote(strrev($find)).'/', strrev($replace), strrev($string), 1));
echo $result; //Output: Round brackets (parentheses) "()", square brackets "[]"
Use the "$" on a reg expression to match the end of the string
$string = 'The quick brown fox jumps over the lazy fox';
echo preg_replace('/fox$/', 'dog', $string);
//output
'The quick brown fox jumps over the lazy dog'
For the interested: I've written a function that utilises preg_match so that you're able to replace from right hand side using regex.
function preg_rreplace($search, $replace, $subject) {
preg_match_all($search, $subject, $matches, PREG_SET_ORDER);
$lastMatch = end($matches);
if ($lastMatch && false !== $pos = strrpos($subject, $lastMatchedStr = $lastMatch[0])) {
$subject = substr_replace($subject, $replace, $pos, strlen($lastMatchedStr));
}
return $subject;
}
Or as a shorthand combination/implementation of both options:
function str_rreplace($search, $replace, $subject) {
return (false !== $pos = strrpos($subject, $search)) ?
substr_replace($subject, $replace, $pos, strlen($search)) : $subject;
}
function preg_rreplace($search, $replace, $subject) {
preg_match_all($search, $subject, $matches, PREG_SET_ORDER);
return ($lastMatch = end($matches)) ? str_rreplace($lastMatch[0], $replace, $subject) : $subject;
}
based on https://stackoverflow.com/a/3835653/3017716 and https://stackoverflow.com/a/23343396/3017716
精彩评论