PHP Multi Byte str_replace?

4 Cevap php

Ben bir UTF-8 dizesi ve str_replace düzgün multi-byte dizeleri işleyemez kullanıyorum çünkü PHP aksanlı karakter değiştirme yapmak ama korkak sonuçlar, benim tahminim olmanın almaya çalışıyorum ..

$accents_search     = array('á','à','â','ã','ª','ä','å','Á','À','Â','Ã','Ä','é','è',
'ê','ë','É','È','Ê','Ë','í','ì','î','ï','Í','Ì','Î','Ï','œ','ò','ó','ô','õ','º','ø',
'Ø','Ó','Ò','Ô','Õ','ú','ù','û','Ú','Ù','Û','ç','Ç','Ñ','ñ'); 

$accents_replace    = array('a','a','a','a','a','a','a','A','A','A','A','A','e','e',
'e','e','E','E','E','E','i','i','i','i','I','I','I','I','oe','o','o','o','o','o','o',
'O','O','O','O','O','u','u','u','U','U','U','c','C','N','n'); 

$str = str_replace($accents_search, $accents_replace, $str);

Bulgular alıyorum:

Ørjan Nilsen -> �orjan Nilsen

Beklenen Sonuç:

Ørjan Nilsen -> Orjan Nilsen

Düzenleme: Ben dahili karakter işleyicisi ne söyleyebilirim bu kadar, ilgili tüm dizeleri UTF-8 olup, ayrıca $ str değeri UTF-8 (() mb_internal_encoding göre) UTF-8 set var ettik. Str_replace () karakter setleri algılar ve onları doğru kullanıyor mu?

4 Cevap

Dize yerini aldı gibi görünüyor, giriş kodlama ve dosya kodlama uyumsuzluğu çünkü.

Php belgelerine göre str_replace işlevi herhangi bir veri kaybı olmadan UTF-8 kodlanmış metin işlemek anlamına gelir, ikili-güvenlidir.

Bu Unicode normalization form D (NFD) ve Unicode karakter özelliklerini kullanarak aksan kaldırmak mümkündür.

NFD (bir mektup) "KÜÇÜK LATİN MEKTUBU U ö" den "ü" noktalı harfler gibi bir şey dönüştürür "KÜÇÜK LATİN MEKTUBU U" (mektup) ve "BİRLEŞTİRİLMESİ ö" (bir harf) için.

header('Content-Type: text/plain; charset=utf-8');

$test = implode('', array('á','à','â','ã','ª','ä','å','Á','À','Â','Ã','Ä','é','è',
'ê','ë','É','È','Ê','Ë','í','ì','î','ï','Í','Ì','Î','Ï','œ','ò','ó','ô','õ','º','ø',
'Ø','Ó','Ò','Ô','Õ','ú','ù','û','Ú','Ù','Û','ç','Ç','Ñ','ñ'));

$test = Normalizer::normalize($test, Normalizer::FORM_D);

// Remove everything that's not a "letter" or a space (e.g. diacritics)
// (see http://de2.php.net/manual/en/regexp.reference.unicode.php)
$pattern = '/[^\pL ]/u';

echo preg_replace($pattern, '', $test);

Çıktı:

aaaaªaaAAAAAeeeeEEEEiiiiIIIIœooooºøØOOOOuuuUUUcCNn

Normalizer sınıfı, PECL intl package parçasıdır. (Algoritma kendisi ben bir süre önce PHP implementation a yazdı. Çok karmaşık değil ama afaik karakter dönüşümlerin bir sürü yüklemek gerekiyor.)

(Ben bunu yeterince yaygın bilinen değil güzel bir tekniktir düşünüyorum çünkü geç bu iki ay ekliyorum.)

Bu fonksiyon tanımı deneyin:

if (!function_exists('mb_str_replace')) {
    function mb_str_replace($search, $replace, $subject) {
        if (is_array($subject)) {
            foreach ($subject as $key => $val) {
                $subject[$key] = mb_str_replace((string)$search, $replace, $subject[$key]);
            }
            return $subject;
        }
        $pattern = '/(?:'.implode('|', array_map(create_function('$match', 'return preg_quote($match[0], "/");'), (array)$search)).')/u';
        if (is_array($search)) {
            if (is_array($replace)) {
                $len = min(count($search), count($replace));
                $table = array_combine(array_slice($search, 0, $len), array_slice($replace, 0, $len));
                $f = create_function('$match', '$table = '.var_export($table, true).'; return array_key_exists($match[0], $table) ? $table[$match[0]] : $match[0];');
                $subject = preg_replace_callback($pattern, $f, $subject);
                return $subject;
            }
        }
        $subject = preg_replace($pattern, (string)$replace, $subject);
        return $subject;
    }
}