Using str_replace so that it only acts on the first match?

后端 未结 22 938
醉酒成梦
醉酒成梦 2020-11-22 11:03

I want a version of str_replace() that only replaces the first occurrence of $search in the $subject. Is there an easy solution to thi

相关标签:
22条回答
  • 2020-11-22 11:40
    $str = "/property/details&id=202&test=123#tab-6p";
    $position = strpos($str,"&");
    echo substr_replace($str,"?",$position,1);
    

    Using substr_replace we can replace the occurrence of first character only in string. as & is repeated multiple times but only at first position we have to replace & with ?

    0 讨论(0)
  • 2020-11-22 11:41

    I wondered which one was the fastest, so I tested them all.

    Below you will find:

    • A comprehensive list of all the functions that have been contributed onto this page
    • Benchmark testing for each contrubution (average execution time over 10,000 runs)
    • Links to each answer (for the full code)

    All functions were tested with the same settings:

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

    Functions that only replace the first occurrence of a string within a string:

    • 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%
      

    Functions that only replace the last occurrence of a string within a string:

    • substr_replace($string, $replace, strrpos($string, $search), strlen($search));

      [CONTRIBUTED BY] => oLinkSoftware - modified zombat
      [OOO.OOO.OOO.S] => OOO.OOO.B.S
      [AVERAGE TIME] => 0.0000068083
      [SLOWER BY] => FASTEST
      
    • strrev(implode(strrev($replace), explode(strrev($search), strrev($string), 2)));

      [CONTRIBUTED BY] => oLinkSoftware
      [OOO.OOO.OOO.S] => OOO.OOO.B.S
      [AVERAGE TIME] => 0.0000084460
      [SLOWER BY] => 24.05%
      
    0 讨论(0)
  • 2020-11-22 11:41

    Unfortunately, I don't know of any PHP function which can do this.
    You can roll your own fairly easily like this:

    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));
    }
    
    0 讨论(0)
  • 2020-11-22 11:42

    To expand on zombat's answer (which I believe to be the best answer), I created a recursive version of his function that takes in a $limit parameter to specify how many occurrences you want to replace.

    function str_replace_limit($haystack, $needle, $replace, $limit, $start_pos = 0) {
        if ($limit <= 0) {
            return $haystack;
        } else {
            $pos = strpos($haystack,$needle,$start_pos);
            if ($pos !== false) {
                $newstring = substr_replace($haystack, $replace, $pos, strlen($needle));
                return str_replace_limit($newstring, $needle, $replace, $limit-1, $pos+strlen($replace));
            } else {
                return $haystack;
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-22 11:43

    You can use this:

    function str_replace_once($str_pattern, $str_replacement, $string){ 
    
            if (strpos($string, $str_pattern) !== false){ 
                $occurrence = strpos($string, $str_pattern); 
                return substr_replace($string, $str_replacement, strpos($string, $str_pattern), strlen($str_pattern)); 
            } 
    
            return $string; 
        } 
    

    Found this example from php.net

    Usage:

    $string = "Thiz iz an examplz";
    var_dump(str_replace_once('z','Z', $string)); 
    

    Output:

    ThiZ iz an examplz
    

    This may reduce the performance a little bit, but the easiest solution.

    0 讨论(0)
  • 2020-11-22 11:43

    If you string does not contains any multibyte characters and if you want to replace only one char you can simply use strpos

    Here a function who handle errors

    /**
     * Replace the first occurence of given string
     *
     * @param  string $search  a char to search in `$subject`
     * @param  string $replace a char to replace in `$subject`
     * @param  string $subject
     * @return string
     *
     * @throws InvalidArgumentException if `$search` or `$replace` are invalid or if `$subject` is a multibytes string
     */
    function str_replace_first(string $search , string $replace , string $subject) : string {
        // check params
        if(strlen($replace) != 1 || strlen($search) != 1) {
            throw new InvalidArgumentException('$search & $replace must be char');
        }elseif(mb_strlen($subject) != strlen($subject)){
            throw new InvalidArgumentException('$subject is an multibytes string');
        }
        // search 
        $pos = strpos($subject, $search);
        if($pos === false) {
            // not found
            return $subject;
        }
    
        // replace
        $subject[$replace] = $subject;
    
        return $subject;
    }
    
    0 讨论(0)
提交回复
热议问题