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


当前回答

它没有版本,但解决方案一点也不俗气。

$pos = strpos($haystack, $needle);
if ($pos !== false) {
    $newstring = substr_replace($haystack, $replace, $pos, strlen($needle));
}

非常简单,并且节省了正则表达式的性能损失。

额外的好处:如果你想替换上次出现的字符串,只需使用strrpos来代替strpos。

其他回答

这个函数很大程度上受到@ renoor回答的启发。 它使函数多字节安全。

function str_replace_limit($search, $replace, $string, $limit)
{
    $i = 0;
    $searchLength = mb_strlen($search);

    while(($pos = mb_strpos($string, $search)) !== false && $i < $limit)
    {
        $string = mb_substr_replace($string, $replace, $pos, $searchLength);
        $i += 1;
    }

    return $string;
}

function mb_substr_replace($string, $replacement, $start, $length = null, $encoding = null)
{
    $string = (array)$string;
    $encoding = is_null($encoding) ? mb_internal_encoding() : $encoding;
    $length = is_null($length) ? mb_strlen($string) - $start : $length;

    $string = array_map(function($str) use ($replacement, $start, $length, $encoding){

        $begin = mb_substr($str, 0, $start, $encoding);
        $end = mb_substr($str, ($start + $length), mb_strlen($str), $encoding);

        return $begin . $replacement . $end;

    }, $string);

    return ( count($string) === 1 ) ? $string[0] : $string;
}
function str_replace_once($search, $replace, $subject) {
    $pos = strpos($subject, $search);
    if ($pos === false) {
        return $subject;
    }

    return substr($subject, 0, $pos) . $replace . substr($subject, $pos + strlen($search));
}

For循环解决方案

<?php
echo replaceFirstMatchedChar("&", "?", "/property/details&id=202&test=123#tab-6");

function replaceFirstMatchedChar($searchChar, $replaceChar, $str)
{
    for ($i = 0; $i < strlen($str); $i++) {

        if ($str[$i] == $searchChar) {
            $str[$i] = $replaceChar;
            break;
        }
    }
    return $str;
}

对于字符串

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