PHP Multi Byte str_replace?
-
12-09-2019 - |
Domanda
che sto cercando di fare la sostituzione carattere accentato in PHP, ma ottenere risultati funky, la mia ipotesi che sono perché sto utilizzando uno stringa UTF-8 e str_replace non riesco a gestire correttamente le stringhe 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);
risultati che ottengo:
Ørjan Nilsen -> �orjan Nilsen
Risultato previsto:
Ørjan Nilsen -> Orjan Nilsen
Edit: ho ottenuto il mio gestore di carattere interno impostato su UTF-8 (secondo mb_internal_encoding ()), anche il valore di $ str è UTF-8, in modo da quello che posso dire, tutte le stringhe coinvolte sono UTF -8. Does str_replace () rilevare set char e utilizzarli correttamente?
Soluzione
Sembra che la corda non è stato sostituito, perché la codifica in ingresso e la mancata corrispondenza codifica del file.
Altri suggerimenti
Secondo la documentazione php str_replace funzione è binary-safe, che significa che è in grado di gestire UTF-8
testo codificato, senza alcuna perdita di dati.
E 'possibile rimuovere i segni diacritici utilizzando Unicode forma normalizzazione D (NFD) e il carattere Unicode proprietà.
NFD converte qualcosa come l'umlaut "ü" da "alfabeto latino U con dieresi" (che è una lettera) a "alfabeto latino U" (lettera) e "COMBINAZIONE diaeresis" (non una lettera).
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
La classe normalizzatore fa parte del pacchetto Intl PECL . (L'algoritmo in sé non è molto complicato, ma ha bisogno di caricare un sacco di mapping di caratteri afaik. Ho scritto un applicazione PHP qualche tempo fa).
(sto aggiungendo questi due mesi di ritardo, perché penso che sia una bella tecnica che non è conosciuto abbastanza ampiamente.)
Provare questa definizione di funzione:
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;
}
}