Problemes de codificació per a l’arxiu UTF8 CSV a l’obrir Excel i TextEdit

Com @jlarson va actualitzar amb la informació de què Mac va ser el major culpable, podríem obtenir més informació. Office per Mac té, al menys 2011 i posterior, un suport bastant pobre per llegir formats d’Unicode a l’importar arxius.

El suport UTF-8 sembla ser gairebé inexistent, he llegit uns pocs comentaris sobre com funciona, mentre que la majoria diu que no. Malauradament no tinc cap Mac per provar. Així que de nou: els propis arxius haurien d’estar bé com a UTF-8, però la importació atura el procés.

Vaig escriure una prova ràpida en Javascript per exportar el percentatge de fuites petits i grans UTF-16 escapats, con- / sense BOM, etc.

El codi probablement hauria de ser refactorizado però hauria d’estar bé per a la prova. Podria funcionar millor que UTF-8. Per descomptat, això també sol significar majors transferències de dades, ja que qualsevol glifo té dos o quatre bytes.

Pots trobar un violí aquí:

nicode export sample Fiddle

Tingueu en compte que no fa servir CSV de cap manera en particular. Està destinat principalment per a la conversió pura a URL de dades amb UTF-8, UTF-16 big / little endian i +/- BOM. Hi ha una opció al fiddle per reemplaçar les comes amb pestanyes, però crec que seria una solució bastant difícil i fràgil si funciona.

Normalment s’usa com:

// Initiateencoder = new DataEnc({ mime : 'text/csv', charset: 'UTF-16BE', bom : true});// Convert data to percent escaped textencoder.enc(data);// Get resultvar result = encoder.pay();

Hi ha dues propietats de resultat de l’objecte:

1.) encoder.lead

Aquest és el tipus mime, conjunt de caràcters, etc. per a la URL de dades. Construït a partir d’opcions passades a l’inicialitzador, o també es pot dir .config({ ... new conf ...}).intro() per reconstruir.

data:

Podeu especificar base64, però no hi ha conversió base64 (al menys no tan lluny).

2.) encoder.buf

Aquesta és una cadena amb el percentatge de dades escapats.

La funció .pay() simplement retorna 1.) i 2.) com un.

Codi principal :

function DataEnc(a) { this.config(a); this.intro();}/** http://www.iana.org/assignments/character-sets/character-sets.xhtml* */DataEnc._enctype = { u8 : , // RFC-2781, Big endian should be presumed if none given u16be : , u16le : };DataEnc._BOM = { 'none' : '', 'UTF-8' : '%ef%bb%bf', // Discouraged 'UTF-16BE' : '%fe%ff', 'UTF-16LE' : '%ff%fe'};DataEnc.prototype = { // Basic setup config : function(a) { var opt = { charset: 'u8', mime : 'text/csv', base64 : 0, bom : 0 }; a = a || {}; this.charset = typeof a.charset !== 'undefined' ? a.charset : opt.charset; this.base64 = typeof a.base64 !== 'undefined' ? a.base64 : opt.base64; this.mime = typeof a.mime !== 'undefined' ? a.mime : opt.mime; this.bom = typeof a.bom !== 'undefined' ? a.bom : opt.bom; this.enc = this.utf8; this.buf = ''; this.lead = ''; return this; }, // Create lead based on config // data:,<data> intro : function() { var g = , c = this.charset || '', b = 'none' ; if (this.mime && this.mime !== '') g.Push(this.mime); if (c !== '') { c = c.replace(//g, '').toLowerCase(); if (DataEnc._enctype.u8.indexOf(c) > -1) { c = 'UTF-8'; if (this.bom) b = c; this.enc = this.utf8; } else if (DataEnc._enctype.u16be.indexOf(c) > -1) { c = 'UTF-16BE'; if (this.bom) b = c; this.enc = this.utf16be; } else if (DataEnc._enctype.u16le.indexOf(c) > -1) { c = 'UTF-16LE'; if (this.bom) b = c; this.enc = this.utf16le; } else { if (c === 'copy') c = ''; this.enc = this.copy; } } if (c !== '') g.Push('charset=' + c); if (this.base64) g.Push('base64'); this.lead = 'data:' + g.join(';') + ',' + DataEnc._BOM; return this; }, // Deliver pay : function() { return this.lead + this.buf; }, // UTF-16BE utf16be : function(t) { // U+0500 => %05%00 var i, c, buf = ; for (i = 0; i < t.length; ++i) { if ((c = t.charCodeAt(i)) > 0xff) { buf.Push(('00' + (c >> 0x08).toString(16)).substr(-2)); buf.Push(('00' + (c & 0xff).toString(16)).substr(-2)); } else { buf.Push('00'); buf.Push(('00' + (c & 0xff).toString(16)).substr(-2)); } } this.buf += '%' + buf.join('%'); // Note the hex array is returned, not string with '%' // Might be useful if one want to loop over the data. return buf; }, // UTF-16LE utf16le : function(t) { // U+0500 => %00%05 var i, c, buf = ; for (i = 0; i < t.length; ++i) { if ((c = t.charCodeAt(i)) > 0xff) { buf.Push(('00' + (c & 0xff).toString(16)).substr(-2)); buf.Push(('00' + (c >> 0x08).toString(16)).substr(-2)); } else { buf.Push(('00' + (c & 0xff).toString(16)).substr(-2)); buf.Push('00'); } } this.buf += '%' + buf.join('%'); // Note the hex array is returned, not string with '%' // Might be useful if one want to loop over the data. return buf; }, // UTF-8 utf8 : function(t) { this.buf += encodeURIComponent(t); return this; }, // Direct copy copy : function(t) { this.buf += t; return this; }};

Resposta anterior:

No tinc cap configuració per replicar la seva, però si el seu cas és el mateix que el de @ jlarson, l’arxiu resultant hauria de ser correcte.

Aquesta resposta es va fer un tant llarga, (¿el tema divertit que dius?), però discuteix diversos aspectes de la pregunta, què està passant (probable) i com comprovar realment què està passant de diverses maneres.

TL; DR:

És probable que el text es import com ISO-8859-1, Windows-1252 o similar, i no com UTF-8. Forçar l’aplicació per llegir l’arxiu com UTF-8 mitjançant la importació o altres mitjans.

PS: The UniSearcher és una bona eina per tenir disponible en aquest viatge.

El llarg camí al voltant

La forma “més fàcil” d’estar 100% segurs del que estem veient des d’un editor hexadecimal en el resultat. Alternativament, utilitzeu hexdump, xxd o semblant des de la línia d’ordres per veure el fitxer. En aquest cas, la seqüència de bytes ha de ser la d’UTF-8 tal com es lliura des del script.

Com a exemple, si prenem l’script de jlarson pren el data Array:

data = , 

Aquest es fusiona a la cadena:

 name,city,state<newline> \u0500\u05E1\u0E01\u1054,seattle,washington<newline>

que es tradueix per Unicode a:

 name,city,state<newline> Ԁסกၔ,seattle,washington<newline>

com UTF-8 fa servir ASCII com a base (els bytes amb el bit més alt no establerts són els mateixos que en ASCII ), l’única seqüència especial en les dades de prova és “Ԁ ס ก ၔ” que al seu torn, és:

Code-point Glyph UTF-8---------------------------- U+0500 Ԁ d4 80 U+05E1 ס d7 a1 U+0E01 ก e0 b8 81 U+1054 ၔ e1 81 94

Mirant el bolcat hexadecimal de l’arxiu descarregat:

0000000: 6e61 6d65 2c63 6974 792c 7374 6174 650a name,city,state.0000010: d480 d7a1 e0b8 81e1 8194 2c73 6561 7474 ..........,seatt0000020: 6c65 2c77 6173 6869 6e67 746f 6e0a le,washington.

A la segona línia hi trobem d480 d7a1 e0b8 81e1 8194 que coincideix amb l’anterior:

0000010: d480 d7a1 e0b8 81 e1 8194 2c73 6561 7474 ..........,seatt | | | | | | | | | | | | | | +-+-+ +-+-+ +--+--+ +--+--+ | | | | | | | | | | | | | | | | Ԁ ס ก ၔ , s e a t t

Cap dels altres personatges està destrossat tampoc.

Fes proves similars si vols. El resultat ha de ser el similar.

Per mostra proporcionada â € “, â €, â € œ

També podem fer una ullada a la mostra proporcionada a la pregunta. És probable que assumeixi que el text està representat en Excel / TextEdit per la pàgina de codis 1252.

Per citar Wikipedia en Windows-1252:

Windows-1252 o CP-1252 és una codificació de caràcters de l’alfabet llatí, utilitzada per defecte en els components heretats de Microsoft Windows en anglès i alguns altres idiomes occidentals. És una versió dins del grup de pàgines de codis de Windows. En els paquets LaTeX, se li coneix com “ansinew”.

Recuperant els bytes originals

Per a traduir-se de nou a la seva forma original, podem veure el disseny de pàgina de codi, d’on obtenim:

Character: <â> <€> <”> <,> < > <â> <€> < > <,> < > <â> <€> <œ>U.Hex : e2 20ac 201d 2c 20 e2 20ac 9d 2c 20 e2 20ac 153T.Hex : e2 80 94 2c 20 e2 80 9d* 2c 20 e2 80 9c
  • U és l’abreviatura d’Unicode
  • T és l’abreviatura de Traduït

Per exemple:

â => Unicode 0xe2 => CP-1252 0xe2” => Unicode 0x201d => CP-1252 0x94€ => Unicode 0x20ac => CP-1252 0x80

Els casos especials com 9d no tenen un punt de codi corresponent a CP-1252, simplement els copiem directament.

Nota: si s’observa la cadena danyada copiant el text en un arxiu i fent un bolcat hexadecimal, guardi l’arxiu, per exemple, amb codificació UTF-16 per obtenir els valors Unicode com es representen a la taula. P. ex a Vim:

set fenc=utf-16# Orset fenc=ucs-2

Bytes a UTF-8

Després combinem el resultat, la línia T.Hex, en UTF-8. En les seqüències UTF-8, els bytes estan representats per un el byte principal ens diu quants bytes subsegüents formen el glifo. Per exemple, si un byte té el valor binari 110x xxxx, sabem que aquest byte i el següent representen un punt de codi. Un total de dos. 1110 xxxx ens diu que són les tres i així successivament. Els valors ASCII no tenen el bit alt establert, de manera que qualsevol byte que coincideixi amb 0xxx xxxx és independent. Un total d’un byte.

0xe2 = 1110 0010compartimiento => 3 bytes => 0xe28094 (em-dash) - 0x2c = 0010 1100compartimiento => 1 byte => 0x2c (coma), 0x2c = 0010 0000compartimiento => 1 byte => 0x20 (espacio) 0xe2 = 1110 0010compartimiento => 3 bytes => 0xe2809d (d-derecha) ” 0x2c = 0010 1100compartimiento => 1 byte => 0x2c (coma), 0x2c = 0010 0000compartimiento => 1 byte => 0x20 (espacio) 0xe2 = 1110 0010compartimiento => 3 bytes => 0xe2809c (izquierda-dq) "

Conclusió; La cadena UTF-8 original era:

—, ”, "

retornant

També podem fer el contrari. La cadena original com bytes:

UTF-8: e2 80 94 2c 20 e2 80 9d 2c 20 e2 80 9c

Valors corresponents a cp-1252:

e2 => â80 => €94 => ”2c => ,20 => <space>...

i així successivament, resultat:

—, â€, “

S’està important a MS Excel

en altres paraules: el problema en qüestió podria ser com importar arxius de text UTF-8 en MS Excel i algunes altres aplicacions. En Excel això es pot fer de diverses maneres.

  • Mètode un:

No guardeu l’arxiu amb una extensió reconeguda per l’aplicació, com .csv, o .txt, sinó omítala per complet o inventi alguna cosa.

com a exemple, guardi l’arxiu com "testfile", sense extensió. Després, en Excel, obriu l’arxiu, confirmi que realment volem obrir aquest arxiu i voilà vam rebre l’opció de codificació. Seleccioneu UTF-8, i l’arxiu ha de llegir-se correctament.

  • Mètode dos:

Utilitzeu dades d’importació en lloc d’obrir l’arxiu. Una cosa com:

Data -> Import External Data -> Import Data

Seleccioneu la codificació i procedeixi.

-vos que Excel i la font seleccionada realment admeten el glifo

També podem provar la compatibilitat de fonts per als caràcters Unicode utilitzant el porta-retalls, de vegades, més amigable. Per exemple, copieu el text d’aquesta pàgina en Excel:

  • pàgina amb punts de codi U + 0E00 a O + 0EFF

Si hi ha suport per als punts de codi, el text s’ha de mostrar bé.

Linux

a Linux, que és principalment UTF-8 a la zona d’usuari, això no hauria de ser un problema. Usant Lliure Office Calc, Vim, etc., mostri els arxius correctament renderitzats.

Per què funciona (o hauria)

encodeURI dels estats d’especificació, (llegiu sec-15.1 .):

La funció encodeURI calcula una nova versió d’un URI en què cada instància de certs caràcters es reemplaça per una, dues, tres o quatre seqüències d’escapament que representen la codificació UTF-8 de l’caràcter.

Simplement podem provar això en la nostra consola, per exemple dient:

>> encodeURI('Ԁסกၔ,seattle,washington')<< "%D4%80%D7%A1%E0%B8%81%E1%81%94,seattle,washington"

Quan vam registrar, les seqüències d’escapament són iguals a les de l’bolcat hexadecimal anterior:

%D4%80%D7%A1%E0%B8%81%E1%81%94 (encodeURI in log) d4 80 d7 a1 e0 b8 81 e1 81 94 (hex-dump of file)

o, provant un codi de 4 bytes:

>> encodeURI('????')<< "%F3%B1%80%81"

si això és no compleix

si res d’això s’aplica podria ajudar si afegeixes

  1. Mostra d’entrada esperada vs sortida danyada, (copiar pegar).
  2. Exemple de bolcat hexadecimal de l’arch ivo de resultats de dades originals.

Deixa un comentari

L'adreça electrònica no es publicarà. Els camps necessaris estan marcats amb *