Pergunta

Eu estou tentando fazer a substituição caractere acentuado em PHP, mas obter resultados funk, meu palpite ser porque eu estou usando um UTF-8 cordas e str_replace não pode tratar adequadamente cordas multi-byte ..

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

Os resultados que eu recebo:

Ørjan Nilsen -> �orjan Nilsen

Resultado esperado:

Ørjan Nilsen -> Orjan Nilsen

Edit: Eu tenho o meu conjunto manipulador de caráter interno para UTF-8 (de acordo com mb_internal_encoding ()), também o valor de $ str é UTF-8, por isso do que eu posso dizer, todas as cordas envolvidas são UTF -8. Será que str_replace () detectar conjuntos de char e usá-los corretamente?

Foi útil?

Solução

Parece que a corda não foi substituído porque a sua codificação de entrada e a incompatibilidade codificação do arquivo.

Outras dicas

De acordo com a documentação do PHP str_replace função é compatível com dados binários, que significa que ele pode lidar com UTF-8 texto codificado sem qualquer perda de dados.

É possível remover sinais diacríticos usando Unicode normalização forma D (NFD) e caracteres Unicode Propriedades.

NFD converte algo como o trema "ü" de "a minúsculo U com trema" (que é uma letra) para "a minúsculo U" (letra) e "trema combinante" (não uma letra).

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

Output:

aaaaªaaAAAAAeeeeEEEEiiiiIIIIœooooºøØOOOOuuuUUUcCNn
classe

O Normalizer faz parte do PECL intl empacotar . (O algoritmo em si não é muito complicado, mas precisa de carregar um monte de mapeamentos de caracteres afaik. Eu escrevi um aplicação PHP um tempo atrás.)

(eu estou adicionando este dois meses de atraso, porque eu acho que é uma técnica agradável que não é conhecido amplamente suficiente.)

Tente esta definição de função:

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;
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top