복붙노트

str_replace를 사용하여 첫 번째 일치에서만 작동하도록 하시겠습니까?

PHP

str_replace를 사용하여 첫 번째 일치에서만 작동하도록 하시겠습니까?

str_replace ()의 $ subject가 $ subject의 첫 번째 항목을 대체하는 버전이 필요합니다. 이 문제에 대한 쉬운 해결책이 있습니까? 아니면 해킹 된 솔루션이 필요합니까?

해결법

  1. ==============================

    1.preg_replace를 사용하여 수행 할 수 있습니다.

    preg_replace를 사용하여 수행 할 수 있습니다.

    function str_replace_first($from, $to, $content)
    {
        $from = '/'.preg_quote($from, '/').'/';
    
        return preg_replace($from, $to, $content, 1);
    }
    
    echo str_replace_first('abc', '123', 'abcdef abcdef abcdef'); 
    // outputs '123def abcdef abcdef'
    

    마술은 선택 사항 인 네 번째 매개 변수 [Limit]에 있습니다. 문서에서 :

    더 효율적인 방법 (대략 3-4 배 빠름)에 대한 zombat의 대답을보십시오.

  2. ==============================

    2.버전은 없지만 솔루션은 전혀 해킹되지 않습니다.

    버전은 없지만 솔루션은 전혀 해킹되지 않습니다.

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

    매우 쉽고 정규 표현식의 성능 저하를 방지합니다.

    보너스 : 마지막 사건을 대체하려면 strpos 대신 strrpos를 사용하십시오.

  3. ==============================

    3.편집 : 두 답변이 업데이트되어 이제는 정확합니다. 함수 타이밍이 여전히 유용하기 때문에 대답을 떠날 것입니다.

    편집 : 두 답변이 업데이트되어 이제는 정확합니다. 함수 타이밍이 여전히 유용하기 때문에 대답을 떠날 것입니다.

    'zombat'및 'too much php'에 의한 대답은 불행히도 정확하지 않습니다. 이것은 zombat가 게시 한 답변에 대한 개정입니다 (의견을 게시할만한 평판이 부족함).

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

    strlen ($ needle) 대신 strlen ($ needle)을 사용하십시오. Zombat의 예는 needle과 replace가 같은 길이 일 경우에만 올바르게 작동합니다.

    다음은 PHP 자신의 str_replace와 같은 서명을 가진 함수에서의 동일한 기능입니다 :

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

    이것은 '너무 많은 PHP'에 대한 수정 된 답변입니다.

    implode($replace, explode($search, $subject, 2));
    

    끝에 2 대신 1을 유의하십시오. 또는 함수 형식으로 :

    function str_replace_first($search, $replace, $subject) {
        return implode($replace, explode($search, $subject, 2));
    }
    

    필자는 두 가지 기능을 시간 측정했으며 일치하는 항목이 없을 때 첫 번째 기능은 두 배 빠릅니다. 일치가 발견되면 속도는 같습니다.

  4. ==============================

    4.나는 어느 것이 가장 빠르는지 궁금해, 그래서 나는 그것들 모두를 시험했다.

    나는 어느 것이 가장 빠르는지 궁금해, 그래서 나는 그것들 모두를 시험했다.

    아래에서 찾을 수 있습니다 :

    모든 기능은 동일한 설정으로 테스트되었습니다.

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

    문자열 내에서 문자열의 첫 번째 항목 만 바꾸는 함수는 다음과 같습니다.

    문자열 내에서 마지막으로 발생한 문자열을 대체하는 함수 :

  5. ==============================

    5.불행히도, 나는 이것을 할 수있는 PHP 함수를 모른다. 다음과 같이 쉽게 자신을 굴릴 수 있습니다.

    불행히도, 나는 이것을 할 수있는 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));
    }
    
  6. ==============================

    6.Regexp를 사용하지 않고도 문자열의 문자열 (대소 문자 구분)을 한도로 대체하는이 작은 함수를 만들었습니다. 그것은 잘 작동합니다.

    Regexp를 사용하지 않고도 문자열의 문자열 (대소 문자 구분)을 한도로 대체하는이 작은 함수를 만들었습니다. 그것은 잘 작동합니다.

    function str_replace_limit($search, $replace, $string, $limit = 1) {
        $pos = strpos($string, $search);
    
        if ($pos === false) {
            return $string;
        }
    
        $searchLen = strlen($search);
    
        for ($i = 0; $i < $limit; $i++) {
            $string = substr_replace($string, $replace, $pos, $searchLen);
    
            $pos = strpos($string, $search);
    
            if ($pos === false) {
                break;
            }
        }
    
        return $string;
    }
    

    사용 예 :

    $search  = 'foo';
    $replace = 'bar';
    $string  = 'foo wizard makes foo brew for evil foo and jack';
    $limit   = 2;
    
    $replaced = str_replace_limit($search, $replace, $string, $limit);
    
    echo $replaced;
    // bar wizard makes bar brew for evil foo and jack
    
  7. ==============================

    7.가장 쉬운 방법은 정규 표현식을 사용하는 것입니다.

    가장 쉬운 방법은 정규 표현식을 사용하는 것입니다.

    다른 방법은 strpos ()와 substr_replace ()를 사용하여 문자열의 위치를 ​​찾는 것입니다.

    그러나 나는 RegExp에 정말로 갈 것이다.

  8. ==============================

    8.

    $string = 'this is my world, not my world';
    $find = 'world';
    $replace = 'farm';
    $result = preg_replace("/$find/",$replace,$string,1);
    echo $result;
    
  9. ==============================

    9.

    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));
    }
    
  10. ==============================

    10.사람들이 말한 것을 보완하면서 전체 문자열이 배열임을 기억하십시오.

    사람들이 말한 것을 보완하면서 전체 문자열이 배열임을 기억하십시오.

    $string = "Lorem ipsum lá lá lá";
    
    $string[0] = "B";
    
    echo $string;
    

    "거기 Borem ipsum 거기"

  11. ==============================

    11.첫 번째 'o'를 'ea'로 바꾸기 :

    첫 번째 'o'를 'ea'로 바꾸기 :

    $a='I love you';
    echo str_replace_first('o','ea',$a);
    
    //output: I leave you
    

    함수:

    function str_replace_first($this,$that,$where)
    {
            $b=strpos($where,$this);
            return substr($where,0,$b).$that.substr($where,$b+1);
    }
    
  12. ==============================

    12.@ renocor의 대답을 확장하기 위해 str_replace ()와 백 워드 호환되는 100 % 함수를 작성했습니다. 즉, str_replace ()를 str_replace_limit ()로 바꾸거나 $ search, $ replace 및 / 또는 $ subject에 대해 배열을 사용하는 경우라도 str_replace_limit ()를 모두 바꿀 수 있습니다.

    @ renocor의 대답을 확장하기 위해 str_replace ()와 백 워드 호환되는 100 % 함수를 작성했습니다. 즉, str_replace ()를 str_replace_limit ()로 바꾸거나 $ search, $ replace 및 / 또는 $ subject에 대해 배열을 사용하는 경우라도 str_replace_limit ()를 모두 바꿀 수 있습니다.

    함수 호출을 ($ string === strval (intval (strval ($ string))))로 바꾸려면 함수 자체가 완전히 포함될 수 있지만 valid_integer ()는 문자열로 제공된 정수를 처리 할 때 오히려 유용한 함수.

    참고 : 가능할 때마다 str_replace_limit ()는 대신 str_replace ()를 사용하므로 str_replace ()에 대한 모든 호출을 성능에 대한 걱정없이 str_replace_limit ()로 바꿀 수 있습니다.

  13. ==============================

    13.내 테스트 결과에 따르면 karim79에서 제공 한 regular_express 투표에 투표하고 싶습니다. (나는 지금 투표 할 충분한 평판이 없다!)

    내 테스트 결과에 따르면 karim79에서 제공 한 regular_express 투표에 투표하고 싶습니다. (나는 지금 투표 할 충분한 평판이 없다!)

    zombat의 솔루션은 너무 많은 함수 호출을 사용하므로 코드를 단순화합니다. PHP 5.4를 사용하여 두 솔루션을 100,000 번 실행했습니다. 결과는 다음과 같습니다.

    $str = 'Hello abc, have a nice day abc! abc!';
    $pos = strpos($str, 'abc');
    $str = substr_replace($str, '123', $pos, 3);
    

    ==> 1.85 초

    $str = 'Hello abc, have a nice day abc! abc!';
    $str = preg_replace('/abc/', '123', $str, 1);
    

    ==> 1.35 초

    보시다시피. preg_replace의 성능은 많은 사람들이 생각하는 것처럼 그렇게 나쁘지 않습니다. 정규 표현식이 복잡하지 않으면 고급 솔루션을 제안합니다.

  14. ==============================

    14.zombat의 대답을 확장하기 위해 (가장 좋은 대답이라고 생각합니다), $ limit 매개 변수를 사용하여 바꿀 횟수를 지정하는 함수의 재귀 버전을 만들었습니다.

    zombat의 대답을 확장하기 위해 (가장 좋은 대답이라고 생각합니다), $ limit 매개 변수를 사용하여 바꿀 횟수를 지정하는 함수의 재귀 버전을 만들었습니다.

    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;
            }
        }
    }
    
  15. ==============================

    15.문자열의 경우

    문자열의 경우

    $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
    
  16. ==============================

    16.이것을 사용할 수 있습니다 :

    이것을 사용할 수 있습니다 :

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

    php.net에서이 예제를 찾았습니다.

    용법:

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

    산출:

    ThiZ iz an examplz
    

    이렇게하면 성능이 약간 떨어지지 만 가장 쉬운 솔루션입니다.

  17. ==============================

    17.이 기능은 @renocor의 대답에 크게 영향을 받았습니다. 이 기능은 멀티 바이트 안전을 보장합니다.

    이 기능은 @renocor의 대답에 크게 영향을 받았습니다. 이 기능은 멀티 바이트 안전을 보장합니다.

    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;
    }
    
  18. ==============================

    18.다음은 약간 수정 된 str_replace () 함수를 래핑하기 위해 만든 간단한 클래스입니다.

    다음은 약간 수정 된 str_replace () 함수를 래핑하기 위해 만든 간단한 클래스입니다.

    우리의 php :: str_replace () 함수는 문자열의 마지막 X 인스턴스 만 바꾸려고 할 때 매우 유용 할 수있는 역방향의 제한된 str_replace ()를 수행 할 수도 있습니다.

    이 두 예제는 모두 preg_replace ()를 사용합니다.

    <?php
    class php {
    
        /**
        * str_replace() from the end of a string that can also be limited e.g. replace only the last instance of '</div>' with ''
        *
        * @param string   $find
        * @param string   $replace
        * @param string   $subject
        * @param int      $replacement_limit | -1 to replace all references
        *
        * @return string
        */
        public static function str_replace($find, $replace, $subject, $replacement_limit = -1) {
            $find_pattern = str_replace('/', '\/', $find);
            return preg_replace('/' . $find_pattern . '/', $replace, $subject, $replacement_limit);
        }
    
        /**
        * str_replace() from the end of a string that can also be limited e.g. replace only the last instance of '</div>' with ''
        *
        * @param string   $find
        * @param string   $replace
        * @param string   $subject
        * @param int      $replacement_limit | -1 to replace all references
        *
        * @return string
        */
        public static function str_rreplace($find, $replace, $subject, $replacement_limit = -1) {
            return strrev( self::str_replace(strrev($find), strrev($replace), strrev($subject), $replacement_limit) );
        }
    }
    
  19. ==============================

    19.

    $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")
    

    거기에 하나 더 추가 공간이 있지만 내 경우에는 배경 스크립트로 중요하지 않았다.

  20. ==============================

    20.문자열에 멀티 바이트 문자가 포함되어 있지 않고 하나의 문자 만 바꾸려면 strpos를 사용하면됩니다.

    문자열에 멀티 바이트 문자가 포함되어 있지 않고 하나의 문자 만 바꾸려면 strpos를 사용하면됩니다.

    오류를 처리하는 함수

    /**
     * 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;
    }
    
  21. ==============================

    21.이것은 나의 첫 번째 대답이다. 나는 그것을 올바르게 할 수 있기를 희망한다. 이 문제에 대해 str_replace 함수의 네 번째 인수를 사용하지 않는 이유는 무엇입니까?

    이것은 나의 첫 번째 대답이다. 나는 그것을 올바르게 할 수 있기를 희망한다. 이 문제에 대해 str_replace 함수의 네 번째 인수를 사용하지 않는 이유는 무엇입니까?

    mixed str_replace ( mixed $search , mixed $replace , mixed $subject [, int &$count ] )
    

    편집 : str_replace의 네 번째 매개 변수는 수행 된 대체 횟수가 할당되는 변수이므로이 대답은 잘못되었습니다. 이것은 preg_replace와 일치하지 않습니다. preg_replace에는 4 번째 매개 변수 $ limit 및 5 번째 매개 변수 & $ count가 있습니다.

  22. ==============================

    22.첫 번째 또는 첫 번째 인스턴스 쌍만 바꾸는 솔루션을 쉽게 찾을 수 있습니다 (카운트 값 제공). 인스턴스의 마지막 또는 마지막 커플을 대체 할 솔루션은 많지 않습니다.

    첫 번째 또는 첫 번째 인스턴스 쌍만 바꾸는 솔루션을 쉽게 찾을 수 있습니다 (카운트 값 제공). 인스턴스의 마지막 또는 마지막 커플을 대체 할 솔루션은 많지 않습니다.

    어쩌면 str_replace ($ find, $ replace, $ subject, -3)와 같은 것이 마지막 세 인스턴스를 대체해야합니다.

    어쨌든, 그냥 제안.

  23. from https://stackoverflow.com/questions/1252693/using-str-replace-so-that-it-only-acts-on-the-first-match by cc-by-sa and MIT license