我想要str_replace()的一个版本,它只替换$subject中第一次出现的$search。有一个简单的解决方案,还是我需要一个hack的解决方案?


当前回答

最简单的方法是使用正则表达式。

另一种方法是用strpos()找到字符串的位置,然后用substr_replace()

但我真的会选择RegExp。

其他回答

可以用preg_replace完成:

function str_replace_first($search, $replace, $subject)
{
    $search = '/'.preg_quote($search, '/').'/';
    return preg_replace($search, $replace, $subject, 1);
}

echo str_replace_first('abc', '123', 'abcdef abcdef abcdef'); 
// outputs '123def abcdef abcdef'

神奇之处在于可选的第四个参数[Limit]。从文档中可以看到:

[极限]-最大可能 每个中的每个模式的替换 主题字符串。默认为-1 (no 限制)。

不过,请参阅zombat的回答以获得更有效的方法(大约快3-4倍)。

$str = "Hello there folks!"
$str_ex = explode("there, $str, 2);   //explodes $string just twice
                                      //outputs: array ("Hello ", " folks")
$str_final = implode("", $str_ex);    // glues above array together
                                      // outputs: str("Hello  folks")

还有一个额外的空间,但这并不重要,因为它是背景脚本在我的情况下。

我想知道哪一个是最快的,所以我都测试了。

下面你会发现:

这个页面上的所有功能的综合列表 对每个贡献进行基准测试(平均执行时间超过10,000次运行) 链接到每个答案(完整代码)


所有功能都在相同的设置下进行测试:

$string = 'OOO.OOO.OOO.S';
$search = 'OOO'; 
$replace = 'B';

仅替换字符串中字符串第一次出现的函数:

substr_replace($string, $replace, 0, strlen($search)); [CONTRIBUTED BY] => zombat [OOO.OOO.OOO.S] => B.OOO.OOO.S [AVERAGE TIME] => 0.0000062883 [SLOWER BY] => FASTEST replace_first($search, $replace, $string); [CONTRIBUTED BY] => too much php [OOO.OOO.OOO.S] => B.OOO.OOO.S [AVERAGE TIME] => 0.0000073902 [SLOWER BY] => 17.52% preg_replace($search, $replace, $string, 1); [CONTRIBUTED BY] => karim79 [OOO.OOO.OOO.S] => B.OOO.OOO.S [AVERAGE TIME] => 0.0000077519 [SLOWER BY] => 23.27% str_replace_once($search, $replace, $string); [CONTRIBUTED BY] => happyhardik [OOO.OOO.OOO.S] => B.OOO.OOO.S [AVERAGE TIME] => 0.0000082286 [SLOWER BY] => 30.86% str_replace_limit($search, $replace, $string, $count, 1); [CONTRIBUTED BY] => bfrohs - expanded renocor [OOO.OOO.OOO.S] => B.OOO.OOO.S [AVERAGE TIME] => 0.0000083342 [SLOWER BY] => 32.54% str_replace_limit($search, $replace, $string, 1); [CONTRIBUTED BY] => renocor [OOO.OOO.OOO.S] => B.OOO.OOO.S [AVERAGE TIME] => 0.0000093116 [SLOWER BY] => 48.08% str_replace_limit($string, $search, $replace, 1, 0); [CONTRIBUTED BY] => jayoaK [OOO.OOO.OOO.S] => B.OOO.OOO.S [AVERAGE TIME] => 0.0000093862 [SLOWER BY] => 49.26%


仅替换字符串中最后一次出现的字符串的函数:

Substr_replace ($string, $replace, strrpos($string, $search), strlen($search)); [贡献BY] => oLinkSoftware - modified僵尸 [OOO.OOO.OOO。S] => ooo [平均时间]=> 0.0000068083 [慢]=>最快 Strrev (implode(Strrev ($replace), explosion (Strrev ($search), Strrev ($string), 2))); [贡献BY] => oLinkSoftware [OOO.OOO.OOO。S] => ooo [平均时间]=> 0.0000084460 [慢]=> 24.05%

对于字符串

$string = 'OOO.OOO.OOO.S';
$search = 'OOO';
$replace = 'B';

//replace ONLY FIRST occurance of "OOO" with "B"
    $string = substr_replace($string,$replace,0,strlen($search));
    //$string => B.OOO.OOO.S

//replace ONLY LAST occurance of "OOOO" with "B"
    $string = substr_replace($string,$replace,strrpos($string,$search),strlen($search)) 
    //$string => OOO.OOO.B.S

    //replace ONLY LAST occurance of "OOOO" with "B"
    $string = strrev(implode(strrev($replace),explode(strrev($search),strrev($string),2)))
    //$string => OOO.OOO.B.S

对于单个字符

$string[strpos($string,$search)] = $replace;


//EXAMPLE

$string = 'O.O.O.O.S';
$search = 'O';
$replace = 'B';

//replace ONLY FIRST occurance of "O" with "B" 
    $string[strpos($string,$search)] = $replace;  
    //$string => B.O.O.O.S

//replace ONLY LAST occurance of "O" with "B" 
    $string[strrpos($string,$search)] = $replace; 
    // $string => B.O.O.B.S

不幸的是,我不知道任何PHP函数可以做到这一点。 你可以像这样很容易地自己卷:

function replace_first($find, $replace, $subject) {
    // stolen from the comments at PHP.net/str_replace
    // Splits $subject into an array of 2 items by $find,
    // and then joins the array with $replace
    return implode($replace, explode($find, $subject, 2));
}