Frage

Ich möchte sicher, dass einige String-Ersatz machen, das ich renne sind Multi-Byte-sicher. Ich habe ein paar mb_str_replace Funktionen rund um das Netz gefunden, aber sie sind langsam. Ich spreche 20% zu erhöhen, nachdem vielleicht 500-900 Bytes durchquert.

Alle Empfehlungen? Ich denke über die Verwendung von preg_replace wie es nativer ist und kompiliert in so dass es schneller sein könnte. Irgendwelche Gedanken würden geschätzt.

War es hilfreich?

Lösung

Andere Tipps

Als Codierung ist eine echte Herausforderung, wenn es Eingaben von überall (UTF-8 oder andere), ziehe ich nur multibyte sichere Funktionen. Für str_replace, ich bin mit dieser einen die schnell genug ist.

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

Hier ist meine Implementierung basiert weg Alain Antwort :

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

Seine keine Zeichencodierung akzeptieren, obwohl ich nehme an, Sie es über mb_regex_encoding .

Meine Einheit Prüfungen bestehen:

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

Am besten bewerteten Hinweis auf http://php.net/manual/en /ref.mbstring.php#109937 sagt str_replace Werke für Multibyte-Strings.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top