2012-03-27 7 views
8

Uso la libreria iconv per interfacciare da una moderna sorgente di input che utilizza UTF-8 in un sistema legacy che utilizza Latin1, alias CP1252 (superset di ISO-8859-1).Perché iconv può convertire la forma precomposta ma non la forma scomposta di "É" (da UTF-8 a CP1252)

L'interfaccia non è riuscita a convertire la stringa francese "Éducation", dove "É" è stato codificato come esadecimale 45 CC 81. Si noti che la codifica della destinazione ha un carattere "É", codificato come C9.

Perché iconv non è in grado di convertire "É"? Ho verificato che lo strumento da riga di comando iconv disponibile con MacOS X 10.7.3 indica che non può essere convertito e che anche il modulo iconv PERL non funziona.

Questo è ancora più sconcertante che la forma precomposta del carattere "É" (codificata come C3 89) converta perfettamente.

Si tratta di un bug con iconv o mi sono perso qualcosa?

Nota che ho anche lo stesso problema se provo a convertire da UTF-16 (dove "É" è codificato come 00 C9 composto o 00 45 03 01 decomposto).

risposta

5

Purtroppo iconv infatti non tratta con i personaggi decomposti in UTF-8, ad eccezione della versione installata su Mac OS X.

Quando si tratta di nomi di file Mac, è possibile utilizzare iconv con il "utf8- mac "opzione set di caratteri. Prende anche in considerazione alcuni idiosyncrasies of the Mac decomposed form.

Tuttavia, le versioni non-mac di iconv o libiconv non supportano questo e non sono riuscito a trovare le origini utilizzate su Mac che forniscono questo supporto.

Sono d'accordo con te che iconv dovrebbe essere in grado di gestire sia le forme NFD sia quelle NFD di UTF8, ma fino a quando qualcuno rattoppa le fonti dobbiamo rilevarlo manualmente e affrontarlo prima di passare a iconv.

Di fronte a questo fastidioso problema, ho usato il modulo Unicode :: Normalize di Perl come suggerito da Jukka.

#!/usr/bin/perl 

use Encode qw/decode_utf8 encode_utf8/; 
use Unicode::Normalize; 

while (<>) { 
    print encode_utf8(NFC(decode_utf8 $_)); 
} 
0

Utilizzare un normalizer (in questo caso, per modulo di normalizzazione C) prima di chiamare iconv.

Un programma che si occupa di codifiche di caratteri (diverse rappresentazioni di caratteri o, più esattamente, punti di codice, come sequenze di byte) e di conversione tra di esse dovrebbe trattare le forme precomposte e composte come distinte. La É decomposta è due punti di codice e in quanto tale distinta dalla É precomposta, che è un punto di codice.

+1

Grazie. Ciò non risponde alla domanda perché iconv mappa il carattere precomposto alla codifica di destinazione, ma non il carattere (chiaramente distinto) decomposto. Perché non entrambi? Perché non il secondo invece del primo? Per uno strumento/libreria di conversione, si tratta di un errore, se non di un bug. –

+0

@ Jean-Denis Muys, perché la forma precomposta è un carattere Unicode, che è rappresentabile nella codifica di destinazione secondo le tabelle di mappatura, mentre la forma scomposta è di due caratteri Unicode e quest'ultima non è rappresentabile in windows-1252 (CP1252) . La corrispondenza tra queste forme non esiste al livello delle codifiche dei caratteri; è un problema di protocollo di livello superiore (ed è un'equivalenza di un tipo specifico, non di identità). –

+1

Si è effettivamente errati. Non c'è motivo per non mappare un personaggio scomposto nel suo equivalente CP-1252.Se "É" sta usando una rappresentazione o l'altra, può - e dovrebbe - essere mappata al carattere "É" del CP-1252. –

Problemi correlati