PHP替换字符串中最后一次出现的字符串?


Answers:


228

您可以使用此功能:

function str_lreplace($search, $replace, $subject)
{
    $pos = strrpos($subject, $search);

    if($pos !== false)
    {
        $subject = substr_replace($subject, $replace, $pos, strlen($search));
    }

    return $subject;
}

无论如何,这仍然返回了真实。考虑将其修改为:if($ pos){$ subject = substr_replace($ subject,$ replace,$ pos,strlen($ search)); 返回$ subject; } else {返回false;}
Jazzy

4
@Jason无论如何都不会返回TRUE。无论如何,它将返回一个字符串。如果替换不能使其返回原来的$subject,就像substr_replace str_replace做的。
Mischa

@Mischa在这种情况下不是一样吗?我试图做类似!str_lreplace的事情,但是如果它没有返回false,就被认为是真的,对吧?无论哪种方式,这都对我有所帮助,我对此表示赞赏。谢谢。
爵士乐

1
这怎么工作?strpos — Find the position of the first occurrence of a substring in a string-编辑:哇。php天才们真的做了一个叫做strposand 的函数strrpos。谢谢....
BarryBones41

1
@Barry这是一个情况下PHP不应该怪:-)名称上图案几十年的老strstrstrrstr标准C库,这是相同的功能。(但他们必须更改名称吗?)
Alexis

30

另一种1-liner但没有预浸料:

$subject = 'bourbon, scotch, beer';
$search = ',';
$replace = ', and';

echo strrev(implode(strrev($replace), explode(strrev($search), strrev($subject), 2))); //output: bourbon, scotch, and beer

3
FWIW,公认的解决方案比该解决方案快35%。
JustCarty

27
$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

我认为最酷的解决方案仍然很容易理解。
Blackbam

为什么所有反向的字符串都可以使用?使用正则表达式时,是否有一些(我认为)特定的性能提升?
卡马菲瑟

不,它实际上会降低性能,但这是因为您只希望最后一次出现,因此将搜索范围限制为一个,然后反转所有内容(如果您想要第一次出现,则不必反转任何内容)
Tofandel

15

以下相当紧凑的解决方案使用PCRE正向超前断言来匹配目标子字符串的最后一次出现,即该子字符串的出现,然后再出现同一子字符串的任何其他出现。因此,例如将替换last 'fox''dog'

$string = 'The quick brown fox, fox, fox jumps over the lazy fox!!!';
echo preg_replace('/(fox(?!.*fox))/', 'dog', $string);

输出: 

The quick brown fox, fox, fox jumps over the lazy dog!!!

5
这个想法很好,但是代码却不是。它必须是:$string = 'The quick brown fox, fox, fox jumps over the lazy fox!!!'; echo preg_replace('/(fox(?!.*fox))/', 'dog', $string);
Roemer

确实,我发布的代码将“ fox”的所有实例(最后一个实例更改为“ dog”)更改了,但是我们想要的却恰恰相反。感谢您指出将?=替换为?!解决问题。
约翰·桑德森

11

您可以这样做:

$str = 'Hello world';
$str = rtrim($str, 'world') . 'John';

结果是“你好约翰”;

问候


4
只要没有重复的字符,此方法就起作用。在我的情况下,我要从存档日期中删除页码,所以我使用的是“ 2015-12 / 2”,它将所有/和所有2个从结尾移到“ 2015-1”。
Mike Mike

仅当最后搜索的单词是最后一个单词且之后没有其他字符时,此方法才起作用。
AwesomeGuy

这是行不通的,因为rtrim它不符合您的思维方式。它将从头开始以任何顺序删除搜索字符串中存在的所有字符(并始终添加替换字符),例如“ Hello word”->“ Hello John”,“ Hello Lord”->“ Hello John”,“ Hello”电机”->“ Hello motJohn”,“ Hello worldy”->“ Hello worldyJohn”。
杰克

5

这也将起作用:

function str_lreplace($search, $replace, $subject)
{
    return preg_replace('~(.*)' . preg_quote($search, '~') . '(.*?)~', '$1' . $replace . '$2', $subject, 1);
}

UPDATE稍微简洁一些的版本(http://ideone.com/B8i4o):

function str_lreplace($search, $replace, $subject)
{
    return preg_replace('~(.*)' . preg_quote($search, '~') . '~', '$1' . $replace, $subject, 1);
}

我做错了吗?如果是这样,请忽略我:) ||| echo str_lreplace(“ x”,“ y”,“这个x或那个x”);=>输出:“ y”参见:ideone.com/UXuTo
edorian

@edorian:糟糕!抱歉,我急忙发布,正确的版本在这里:ideone.com/vR073
Alix Axel 2010年

5

只需一行代码(答案很晚,但是值得添加):

$string = 'The quick brown fox jumps over the lazy dog';
$find_me = 'dog';

preg_replace('/'. $find_me .'$/', '', $string);

结尾的$表示字符串的结尾。


5

这是一个古老的问题,但是为什么每个人都忽略了最简单的基于正则表达式的解决方案?普通的正则表达式量词是贪婪的,人们!如果要查找某个模式的最后一个实例,只需坚持.*在它的前面。这是如何做:

$text = "The quick brown fox, fox, fox, fox, jumps over etc.";
$fixed = preg_replace("((.*)fox)", "$1DUCK", $text);
print($fixed);

它将像预期的那样将“ fox” 的最后一个实例替换为“ DUCK”,并打印:

The quick brown fox, fox, fox, DUCK, jumps over etc.

1
谢谢!环绕我的表情来完成此功能的完美功能。就我而言,我将最后一个逗号替换为“和”。很高兴我在此答案列表中向下滚动了一点。
rlhane

3
$string = "picture_0007_value";
$findChar =strrpos($string,"_");
if($findChar !== FALSE) {
  $string[$findChar]=".";
}

echo $string;

除了代码中的错误外,Faruk Unal拥有最佳的解决方案。一种功能可以解决问题。


您需要检查$ findChar是否为假(与接受的答案相同)。如果该字符串不包含搜索到的字符串,则会引起注意,并且第一个字符将被替换。
毛茸茸的

这很棒,但是就目前而言,它只能用1个字符替换1个字符。
皮特

3

您可以使用strrpos()查找最后一个匹配项。

$string = "picture_0007_value";
$findChar =strrpos($string,"_");

$string[$findChar]=".";

echo $string;

输出:picture_0007.value


2

接受答案的简写

function str_lreplace($search, $replace, $subject){ 
    return is_numeric($pos=strrpos($subject,$search))?
    substr_replace($subject,$replace,$pos,strlen($search)):$subject;
}

2

简短版本:

$NewString = substr_replace($String,$Replacement,strrpos($String,$Replace),strlen($Replace));

0

在正则表达式上使用“ $”以匹配字符串的结尾

$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'

4
仅当最后一次出现在字符串ideone.com/nbNSNq
cawecoy 2014年

1
如果在最后一个“ fox”之后出现任何其他字符,则此功能将无效。
John Sonderson

0

感兴趣的人:我编写了一个使用preg_match的函数,以便您可以使用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;
}

或作为两种选择的简化组合/实现:

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;
}

基于https://stackoverflow.com/a/3835653/3017716https://stackoverflow.com/a/23343396/3017716

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.