2009-11-06 56 views
5

Al tratar de arreglar un archivo PML (Palm Markup Language), parece que mi archivo de prueba tiene caracteres que no son ASCII y que hace que MakeBook se queje. La solución sería eliminar todos los caracteres no ASCII en el PML.Como eliminar ascii extendido usando python?

Así que en el intento de solucionar este problema en Python, que tienen

import unicodedata, fileinput 

for line in fileinput.input(): 
    print unicodedata.normalize('NFKD', line).encode('ascii','ignore') 

Sin embargo, esto resulta en un error que la línea debe ser "Unicode, no str". Aquí hay un fragmento de archivo.

\B1a\B \tintense, disordered and often destructive rage†.†.†.\t 

No estoy seguro de cómo pasar correctamente la línea para que se procese en este punto.

+0

¿Quieres filtrar cualquier carácter cuyo valor ASCII es mayor que 255? –

+0

Estrictamente hablando, no existe el ASCII extendido. ASCII define valores de 0 a 127. Cualquier cosa más alta que eso solo puede interpretarse arbitrariamente. Tal vez deba usar el término * caracteres que no sean ASCII *. – dreamlax

+0

Relacionados: Función de escape seguro para la salida del terminal http://stackoverflow.com/questions/437476/safe-escape-function-for-terminal-output – jfs

Respuesta

0

Cuando lee desde un archivo en Python obtiene cadenas de bytes, también conocidas como "str" ​​en Python 2.xy anteriores. Debe convertirlos al tipo "Unicode" utilizando el método decode. por ejemplo:

line = line.decode('latin1') 

Reemplazar 'latin1' con la codificación correcta.

5

Pruebe print line.decode('iso-8859-1').encode('ascii', 'ignore') - eso debería estar mucho más cerca de lo que desea.

+0

Esto parece funcionar, aunque MakeBook ahora se queja de los códigos de control ilegales. –

+0

@Jauder, también puede eliminar los códigos de control, por ejemplo, después del 'clean = '' anterior.join (c para c en línea si ord (c)> = 32) '(elimina TODOS los códigos de control incluyendo nueva línea y retorno de carro - ajústelo al gusto, realmente no podemos hacerlo por usted sin saber QUÉ códigos de control desea ¡retirar!-). –

+0

@Alex, si lo supiera, lo haría =). El problema es que estoy trabajando con solo un programa Java sin fuente disponible que solo emite un mensaje de error críptico. http://gist.github.com/227882 –

5

Que le gustaría tratar line como datos codificados en ASCII, así que la respuesta es decodificar en texto usando el códec ascii:

line.decode('ascii')

Esto elevará los errores para los datos que no es, de hecho, Codificado en ASCII Esta es la forma de ignorar esos errores:

line.decode('ascii', 'ignore').

Esto le proporciona texto, en forma de una instancia unicode. Si prefiere trabajar con datos (ASCII-codificado) en lugar de texto, puede volver a codificar a volver una instancia str o bytes (dependiendo de la versión de Python):

line.decode('ascii', 'ignore').encode('ascii')

2

a DROP los caracteres que no son ASCII usan line.decode(your_file_encoding).encode('ascii', 'ignore'). Pero probablemente es mejor utilizar secuencias de escape de PLM para ellos:

import re 

def escape_unicode(m): 
    return '\\U%04x' % ord(m.group()) 

non_ascii = re.compile(u'[\x80-\uFFFF]', re.U) 

line = u'\\B1a\\B \\tintense, disordered and often destructive rage\u2020.\u2020.\u2020.\\t' 
print non_ascii.sub(escape_unicode, line) 

Esto da salida a \B1a\B \tintense, disordered and often destructive rage\U2020.\U2020.\U2020.\t.

de caída no ASCII y caracteres de control con la expresión regular es fácil también (esto puede ser utilizado con seguridad después de escapar):

regexp = re.compile('[^\x09\x0A\x0D\x20-\x7F]') 
regexp.sub('', line) 
Cuestiones relacionadas