2011-04-08 15 views
13

¿Cómo puedo leer un archivo de texto utf-8 codificado en en Mathematica?Lectura de un archivo de texto codificado UTF-8 en Mathematica

Esto es lo que estoy haciendo ahora:

text = Import["charData.txt", "Text", CharacterEncoding -> "UTF8"]; 

pero me dice que

$CharacterEncoding::utf8: "The byte sequence {240} could not be interpreted as a character in the UTF-8 character encoding" 

y así sucesivamente. No estoy seguro por qué. Creo que el archivo es válido utf-8.

Aquí está el archivo que estoy tratando de leer:

http://dl.dropbox.com/u/38623/charData.txt

+0

La décima línea, que contiene ": Ba" tiene caracteres que se ven diferentes en Mathematica, Safari y TextEdit/BBEdit. (No voy a interpretar esto, solo lo señalo) –

+2

Parece que no es compatible con la secuencia UTF-8 de 4 bytes. Probablemente un error. – kennytm

+0

@Brett, ditto TextMate/Chrome –

Respuesta

9

versión corta: funcionalidad UTF-8 de Mathematica no funciona para los códigos de caracteres con más de 16 bits. Use codificación UTF-16 en su lugar, si es posible. Pero tenga en cuenta que el tratamiento de Mathematica de los códigos de caracteres de más de 17 bits generalmente no funciona. La versión larga sigue ...

Como señalaron numerosos comentaristas, el problema parece ser con el soporte de Mathematica para caracteres Unicode cuyos códigos son mayores que 16 bits. El primer carácter de este tipo en el archivo de texto citado es U+20B9B() que aparece en la línea 10.

Algunas versiones del front-end de Mathematica (como 8.0.1 en Windows 7 de 64 bits) pueden manejar el carácter en cuestión entramos directamente:

In[1]:= $c=""; 

Pero nos encontramos con problemas si se intenta crear el personaje de su Unicode:

In[2]:= 134043 // FromCharacterCode 

During evaluation of In[2]:= FromCharacterCode::notunicode: 
A character code, which should be a non-negative integer less 
than 65536, is expected at position 1 in {134043}. >> 
Out[2]= FromCharacterCode[134043] 

Uno se pregunta entonces, lo que hace pensar Mathematica es el código para esta Char acter?

In[3]:= $c // ToCharacterCode 
     BaseForm[%, 16] 
     BaseForm[%, 2] 

Out[3]= {55362,57243} 
Out[4]//BaseForm= {d842, df9b} 
Out[5]//BaseForm= {1101100001000010, 1101111110011011} 

En lugar de un único valor Unicode como era de esperar, se obtienen dos códigos que suceden para que coincida con la representación UTF-16 de ese carácter. Mathematica puede realizar la transformación inversa, así:

In[6]:= {55362,57243} // FromCharacterCode 

Out[6]= 

Entonces, ¿cuál es la concepción de la codificación UTF-8 de este personaje de Mathematica?

In[7]:= ExportString[$c, "Text", CharacterEncoding -> "UTF8"] // ToCharacterCode 
     BaseForm[%, 16] 
     BaseForm[%, 2] 

Out[7]= {237,161,130,237,190,155} 
Out[8]//BaseForm= {ed, a1, 82, ed, be, 9b} 
Out[9]//BaseForm= {11101101, 10100001, 10000010, 11101101, 10111110, 10011011} 

El lector atento lugar que este es el UTF-8 encoding de la codificación UTF-16 del personaje. ¿Puede Mathematica decodificar esto, um, codificación interesante?

In[10]:= ImportString[ 
      ExportString[{237,161,130,237,190,155}, "Byte"] 
     , "Text" 
     , CharacterEncoding -> "UTF8" 
     ] 

Out[10]= 

Sí, puede! ¿Y qué?

¿Qué tal el verdadero UTF-8 expresión de este carácter:

In[11]:= ImportString[ 
      ExportString[{240, 160, 174, 155}, "Byte"] 
     , "Text" 
     , CharacterEncoding -> "UTF8" 
     ] 
Out[11]= $CharacterEncoding::utf8: The byte sequence {240} could not be 
interpreted as a character in the UTF-8 character encoding. >> 
$CharacterEncoding::utf8: The byte sequence {160} could not be 
interpreted as a character in the UTF-8 character encoding. >> 
$CharacterEncoding::utf8: The byte sequence {174} could not be 
interpreted as a character in the UTF-8 character encoding. >> 
General::stop: Further output of $CharacterEncoding::utf8 will be suppressed 
during this calculation. >> 
ð ® 

... pero vemos el fracaso reportado en la pregunta original.

¿Qué tal UTF-16?UTF-16 no está en la lista de codificaciones de caracteres válidas, pero "Unicode" es. Como ya hemos visto que Mathematica parece utilizar UTF-16 como su formato nativo, vamos a darle una turbina (el uso de big endian UTF-16 con un orden de bytes-marca):

In[12]:= ImportString[ 
      ExportString[ 
      FromDigits[#, 16]& /@ {"fe", "ff", "d8", "42", "df", "9b"} 
      , "Byte" 
      ] 
     , "Text" 
     , CharacterEncoding -> "Unicode" 
     ] 
Out[12]= 

Funciona. Como un experimento más completo, I re-encoded the cited text file de la pregunta en UTF-16 e importó con éxito.

La documentación de Mathematica no dice mucho sobre este tema. Es interesante observar que la mención de Unicode en Mathematica parece ir acompañada de la suposición de que los códigos de caracteres contienen 16 bits. Ver, por ejemplo, referencias a Unicode en Raw Character Encodings.

La conclusión que se puede extraer de esto es que falta el soporte de Mathematica para la transcodificación UTF-8 para los códigos de más de 16 bits. UTF-16, el aparente formato interno de Mathematica, parece funcionar correctamente. Así que eso es una solución si está en una posición para volver a codificar sus archivos y, puede aceptar que las cadenas resultantes estarán realmente en formato UTF-16, no cadenas Unicode verdaderas.

PostScript

Poco después de escribir esto, yo le trató de volver a abrir el cuaderno de Mathematica que lo contiene. Cada aparición del personaje problemático en el cuaderno había sido aniquilada y reemplazada por un galimatías. Supongo que aún hay más errores Unicode que resolver, incluso en Mathematica 8.0.1;)

+0

Tengo curiosidad, ¿qué versión de Mathematica usas, en qué plataforma? Con la versión 8 en Windows XP, la interfaz no puede manejar. Al pegarlo (no puedo ingresar usando el IME), obtengo una secuencia de dos caracteres. Además, de acuerdo con la documentación, la configuración "Unicode" mostrará "valores Unicode en bruto de 2 bytes", lo cual está de acuerdo principalmente con esto (y con sus otros hallazgos). – Szabolcs

+0

@Szabolcs Escribí esto usando Mathematica 8.0.1 en Windows 7 de 64 bits. Solo un segundo, probaré MMa 7 ... (pausa) Sí, funciona allí también para mí. Sin embargo, me acabo de dar cuenta de que cuando volví a abrir el cuaderno que contiene esta respuesta, el personaje en cuestión ahora se muestra como un cuadrado de "carácter faltante". Y el portátil ya no funciona correctamente. Interesante. Los errores van aún más lejos ... – WReach

+1

Lo que podemos aprender de esto es que Mathematica no puede interpretar caracteres que requieren 2 unidades (4 bytes) para codificar en UTF-16, _sin embargo_, deja intactas estas secuencias de 4 bytes. Por lo tanto, los datos aún se pueden exportar a otras aplicaciones (¡incluso copiando la cadena desde el frente y pegándola en otro lugar!) Pero durante el procesamiento de los datos debemos tener en cuenta que estos caracteres se tratarán como secuencias de dos caracteres y, por lo tanto, funciones como StringLength devuelven resultados incorrectos. – Szabolcs

Cuestiones relacionadas