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

后端 未结 22 1198
醉酒成梦
醉酒成梦 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:33

    To expand on @renocor's answer, I've written a function that is 100% backward-compatible with str_replace(). That is, you can replace all occurrences of str_replace() with str_replace_limit() without messing anything up, even those using arrays for the $search, $replace, and/or $subject.

    The function could be completely self-contained, if you wanted to replace the function call with ($string===strval(intval(strval($string)))), but I'd recommend against it since valid_integer() is a rather useful function when dealing with integers provided as strings.

    Note: Whenever possible, str_replace_limit() will use str_replace() instead, so all calls to str_replace() can be replaced with str_replace_limit() without worrying about a hit to performance.

    Usage

    $limit = -1; // No limit
    $new_string = str_replace_limit($search, $replace, $subject, $count, $limit);
    echo $count.' replacements -- '.$new_string;
    

    2 replacements -- bbcbbc

    $limit = 1; // Limit of 1
    $new_string = str_replace_limit($search, $replace, $subject, $count, $limit);
    echo $count.' replacements -- '.$new_string;
    

    1 replacements -- bbcabc

    $limit = 10; // Limit of 10
    $new_string = str_replace_limit($search, $replace, $subject, $count, $limit);
    echo $count.' replacements -- '.$new_string;
    

    2 replacements -- bbcbbc

    Function

     $this_subject){
    
                // Skip values that are arrays (to match str_replace()).
                if(!is_array($this_subject)){
    
                    // Call this function again for
                    $this_function = __FUNCTION__;
                    $subject[$key] = $this_function(
                            $search,
                            $replace,
                            $this_subject,
                            $this_count,
                            $limit
                    );
    
                    // Adjust $count
                    $count += $this_count;
    
                    // Adjust $limit, if not -1
                    if($limit!=-1){
                        $limit -= $this_count;
                    }
    
                    // Reached $limit, return $subject
                    if($limit===0){
                        return $subject;
                    }
    
                }
    
            }
    
            return $subject;
    
        } elseif(is_array($search)){
            // Only treat $replace as an array if $search is also an array (to match str_replace())
    
            // Clear keys of $search (to match str_replace()).
            $search = array_values($search);
    
            // Clear keys of $replace, if applicable (to match str_replace()).
            if(is_array($replace)){
                $replace = array_values($replace);
            }
    
            // Loop through $search array.
            foreach($search as $key => $this_search){
    
                // Don't support multi-dimensional arrays (to match str_replace()).
                $this_search = strval($this_search);
    
                // If $replace is an array, use the value of $replace[$key] as the replacement. If
                // $replace[$key] doesn't exist, just an empty string (to match str_replace()).
                if(is_array($replace)){
                    if(array_key_exists($key, $replace)){
                        $this_replace = strval($replace[$key]);
                    } else {
                        $this_replace = '';
                    }
                } else {
                    $this_replace = strval($replace);
                }
    
                // Call this function again for
                $this_function = __FUNCTION__;
                $subject = $this_function(
                        $this_search,
                        $this_replace,
                        $subject,
                        $this_count,
                        $limit
                );
    
                // Adjust $count
                $count += $this_count;
    
                // Adjust $limit, if not -1
                if($limit!=-1){
                    $limit -= $this_count;
                }
    
                // Reached $limit, return $subject
                if($limit===0){
                    return $subject;
                }
    
            }
    
            return $subject;
    
        } else {
            $search = strval($search);
            $replace = strval($replace);
    
            // Get position of first $search
            $pos = strpos($subject, $search);
    
            // Return $subject if $search cannot be found
            if($pos===false){
                return $subject;
            }
    
            // Get length of $search, to make proper replacement later on
            $search_len = strlen($search);
    
            // Loop until $search can no longer be found, or $limit is reached
            for($i=0;(($i<$limit)||($limit===-1));$i++){
    
                // Replace 
                $subject = substr_replace($subject, $replace, $pos, $search_len);
    
                // Increase $count
                $count++;
    
                // Get location of next $search
                $pos = strpos($subject, $search);
    
                // Break out of loop if $needle
                if($pos===false){
                    break;
                }
    
            }
    
            // Return new $subject
            return $subject;
    
        }
    
    }
    

提交回复
热议问题