开发者

Replace last occurrence of a string in a string

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜