Замена первого вхождения.

Тема в разделе "Как сделать...", создана пользователем Parasol, 17 июл 2009.

Статус темы:
Закрыта.
  1. Parasol

    Parasol Постоялец

    Регистр.:
    7 июл 2007
    Сообщения:
    149
    Симпатии:
    65
    Здравствуйте.

    Подскажите как сделать аналог str_replace но чтобы заменялись не все найденные вхождения, а только первое? :ah:

    Желательно без нахождения позиции вхождения ( strpos )


    с strpos`ом есть, но чёто медленно работает ;(
    Код:
    function str_replace_once($search, $replace, $subject) 
    {
        $firstChar = strpos($subject, $search);
    
        if($firstChar !== false) 
    	{
            $beforeStr = substr($subject,0,$firstChar);
            $afterStr = substr($subject, $firstChar + strlen($search));
            return $beforeStr.$replace.$afterStr;
        }
    	else
    	{
            return $subject;
        }
    }
    

    Буду очень благодарен!
     
  2. KillDead

    KillDead

    Регистр.:
    11 авг 2006
    Сообщения:
    884
    Симпатии:
    540
    PHP:
    function str_replace_once($search$replace$subject
    {
        
    $firstChar strpos($subject$search);
        if(
    $firstChar !== false
     {
            
    $subject substr_replace($subject$replace$firstChar strlen($search));
        }
       return 
    $subject;
        
    }
    так быстрее будет
     
  3. ConstNW

    ConstNW Постоялец

    Регистр.:
    30 июн 2007
    Сообщения:
    132
    Симпатии:
    39
    На строках до 50Кб эта функция будет быстрее работать, чем функция от KillDead. Прирост до 20%.

    К сожалению на строках от 50Кб будет много ресурсов затрачиваться на вызов функции explode. Это давно известный баг.
    PHP:
    function str_replace_once$search$replace$subject )
    {
        
    $parts explode($search$subject2);
        if(
    count($parts) == 1) return $subject;
        return 
    $parts[0].$replace.$parts[1];
    }
     
  4. KillDead

    KillDead

    Регистр.:
    11 авг 2006
    Сообщения:
    884
    Симпатии:
    540
    Ну, если strpos начал тормазить, то объём данных должен быть достаточно большой.
    Сравнение работы для функций strpos(1) и exploid(2) при небольшом тексте для 10000000 замен:
     
  5. ConstNW

    ConstNW Постоялец

    Регистр.:
    30 июн 2007
    Сообщения:
    132
    Симпатии:
    39
    KillDead, не strpos тормозит, а все функции с приставкой substr.
    Если объем строки более 50Кб, то explode начинает тормозить.

    Вот код для тестирования.
    PHP:
    function str_replace_once_1$search$replace$subject )
    {
        
    $firstChar strpos($subject$search);
        if(
    $firstChar !== false)
            
    $subject substr_replace($subject$replace$firstChar strlen($search));
        return 
    $subject;
    }
    function 
    str_replace_once_2$search$replace$subject )
    {
        
    $parts explode($search$subject2);
        if(
    count($parts) == 1) return $subject;
        return 
    $parts[0].$replace.$parts[1];
    }

    $search "ax";
    $replace "zy";
    $subjectSrc "aaaxaaax";
    $subject "";

    //for( $i=0; $i < 9000; $i++) $subject .= $subjectSrc; // 9000 * 8 = 72Kb
    for( $i=0$i 900$i++) $subject .= $subjectSrc// 900 * 8 = 7.2Kb

    echo strlen($subject), "<br />";


    $starttime microtime(true);
    for( 
    $i=0$i 100000$i++) str_replace_once_1$search$replace$subject );
    echo (
    microtime(true) - $starttime), "<br />";

    $starttime microtime(true);
    for( 
    $i=0$i 100000$i++) str_replace_once_2$search$replace$subject );
    echo (
    microtime(true) - $starttime), "<br />";
     
Статус темы:
Закрыта.