Domanda

voglio fare in modo un po 'di sostituzione di stringa è Io corro sono più sicuri di byte. Ho trovato alcune funzioni mb_str_replace giro per la rete ma sono lento. Sto parlando aumento del 20% dopo aver superato forse 500-900 byte attraverso di essa.

Tutti i consigli? Sto pensando di usare preg_replace come è nativo e compilato in modo potrebbe essere più veloce. Ogni pensiero sarebbe apprezzato.

È stato utile?

Soluzione

Come ha detto ci , str_replace è sicuro da usare in UTF-8 contesti, a patto che tutti i parametri sono utf-8 valida, perché non ci sarà alcun incontro ambiguo tra entrambe le stringhe multibyte codificato. Se si controlla la validità del vostro ingresso, allora non avete bisogno di cercare una funzione diversa.

Altri suggerimenti

Come codifica è una vera sfida quando ci sono ingressi da tutto il mondo (utf8 o altri), io preferisco usare solo funzioni multibyte di sicurezza. Per str_replace, sto usando questo uno che è abbastanza veloce.

if (!function_exists('mb_str_replace'))
{
   function mb_str_replace($search, $replace, $subject, &$count = 0)
   {
      if (!is_array($subject))
      {
         $searches = is_array($search) ? array_values($search) : array($search);
         $replacements = is_array($replace) ? array_values($replace) : array($replace);
         $replacements = array_pad($replacements, count($searches), '');
         foreach ($searches as $key => $search)
         {
            $parts = mb_split(preg_quote($search), $subject);
            $count += count($parts) - 1;
            $subject = implode($replacements[$key], $parts);
         }
      }
      else
      {
         foreach ($subject as $key => $value)
         {
            $subject[$key] = mb_str_replace($search, $replace, $value, $count);
         }
      }
      return $subject;
   }
}

Ecco la mia realizzazione, in base al largo risposta di Alain:

/**
 * Replace all occurrences of the search string with the replacement string. Multibyte safe.
 *
 * @param string|array $search The value being searched for, otherwise known as the needle. An array may be used to designate multiple needles.
 * @param string|array $replace The replacement value that replaces found search values. An array may be used to designate multiple replacements.
 * @param string|array $subject The string or array being searched and replaced on, otherwise known as the haystack.
 *                              If subject is an array, then the search and replace is performed with every entry of subject, and the return value is an array as well.
 * @param string $encoding The encoding parameter is the character encoding. If it is omitted, the internal character encoding value will be used.
 * @param int $count If passed, this will be set to the number of replacements performed.
 * @return array|string
 */
public static function mbReplace($search, $replace, $subject, $encoding = 'auto', &$count=0) {
    if(!is_array($subject)) {
        $searches = is_array($search) ? array_values($search) : [$search];
        $replacements = is_array($replace) ? array_values($replace) : [$replace];
        $replacements = array_pad($replacements, count($searches), '');
        foreach($searches as $key => $search) {
            $replace = $replacements[$key];
            $search_len = mb_strlen($search, $encoding);

            $sb = [];
            while(($offset = mb_strpos($subject, $search, 0, $encoding)) !== false) {
                $sb[] = mb_substr($subject, 0, $offset, $encoding);
                $subject = mb_substr($subject, $offset + $search_len, null, $encoding);
                ++$count;
            }
            $sb[] = $subject;
            $subject = implode($replace, $sb);
        }
    } else {
        foreach($subject as $key => $value) {
            $subject[$key] = self::mbReplace($search, $replace, $value, $encoding, $count);
        }
    }
    return $subject;
}

La sua non accetta una codifica dei caratteri, anche se suppongo che si possa impostare tramite mb_regex_encoding .

Il mio test di unità passano:

function testMbReplace() {
    $this->assertSame('bbb',Str::mbReplace('a','b','aaa','auto',$count1));
    $this->assertSame(3,$count1);
    $this->assertSame('ccc',Str::mbReplace(['a','b'],['b','c'],'aaa','auto',$count2));
    $this->assertSame(6,$count2);
    $this->assertSame("\xbf\x5c\x27",Str::mbReplace("\x27","\x5c\x27","\xbf\x27",'iso-8859-1'));
    $this->assertSame("\xbf\x27",Str::mbReplace("\x27","\x5c\x27","\xbf\x27",'gbk'));
}

Le più votate nota sulla http://php.net/manual/en /ref.mbstring.php#109937 dice opere str_replace per le stringhe multibyte.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top