¿Cómo puedo eliminar los caracteres que no son ASCII pero dejar puntos y espacios usando Python?

Estoy trabajando con un archivo .txt. Quiero una cadena del texto del archivo sin caracteres que no sean ASCII. Sin embargo, quiero dejar espacios y puntos. En la actualidad, me estoy quitando esos también. Aquí está el código:

def onlyascii(char): if ord(char)  127: return '' else: return char def get_my_string(file_path): f=open(file_path,'r') data=f.read() f.close() filtered_data=filter(onlyascii, data) filtered_data = filtered_data.lower() return filtered_data 

¿Cómo debo modificar onlyascii () para dejar espacios y puntos? Me imagino que no es demasiado complicado pero no puedo entenderlo.

Puede filtrar todos los caracteres de la cadena que no se pueden imprimir con string.printable , como esto:

 >>> s = "some\x00string. with\x15 funny characters" >>> import string >>> printable = set(string.printable) >>> filter(lambda x: x in printable, s) 'somestring. with funny characters' 

string.printable en mi máquina contiene:

 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ !"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c 

Una forma fácil de cambiar a un códec diferente es mediante el uso de encode () o decode (). En su caso, desea convertir a ASCII e ignorar todos los símbolos que no son compatibles. Por ejemplo, la letra sueca å no es un carácter ASCII:

  >>>s = u'Good bye in Swedish is Hej d\xe5' >>>s = s.encode('ascii',errors='ignore') >>>print s Good bye in Swedish is Hej d 

Editar:

Python3: str -> bytes -> str

 >>>"Hej då".encode("ascii", errors="ignore").decode() 'hej d' 

Python2: unicode -> str -> unicode

 >>> u"hej då".encode("ascii", errors="ignore").decode() u'hej d' 

Python2: str -> unicode -> str (decodificar y codificar en orden inverso)

 >>> "hej d\xe5".decode("ascii", errors="ignore").encode() 'hej d' 

De acuerdo con @artfulrobot, esto debería ser más rápido que filter y lambda:

 re.sub(r'[^\x00-\x7f]',r'', your-non-ascii-string) 

Vea más ejemplos aquí http://stackoverflow.com/questions/20078816/replace-non-ascii-characters-with-a-single-space/20079244#20079244

Tu pregunta es ambigua; las dos primeras oraciones tomadas juntas implican que usted cree que el espacio y el “punto” no son caracteres ASCII. Esto es incorrecto. Todos los caracteres tales que ord (char) <= 127 son caracteres ASCII. Por ejemplo, su función excluye estos caracteres! "# $% & \ '() * +, -. / Pero incluye varios otros, por ejemplo, [] {}.

Por favor, retroceda, piense un poco y edite su pregunta para decirnos qué está tratando de hacer, sin mencionar la palabra ASCII, y por qué cree que los caracteres tales que ord (char)> = 128 son ignorables. También: ¿Qué versión de Python? ¿Cuál es la encoding de sus datos de entrada?

Tenga en cuenta que su código lee todo el archivo de entrada como una sola cadena, y su comentario (“gran solución”) a otra respuesta implica que no le importan las nuevas líneas en sus datos. Si su archivo contiene dos líneas como esta:

 this is line 1 this is line 2 

el resultado sería 'this is line 1this is line 2' … ¿es eso lo que realmente quiere?

Una solución mayor incluiría:

  1. un nombre mejor para la función de filtro que onlyascii
  2. el reconocimiento de que una función de filtro simplemente necesita devolver un valor verdadero si el argumento se va a conservar:

     def filter_func(char): return char == '\n' or 32 <= ord(char) <= 126 # and later: filtered_data = filter(filter_func, data).lower() 

Si desea caracteres ASCII imprimibles, probablemente debería corregir su código para:

 if ord(char) < 32 or ord(char) > 126: return '' 

esto es equivalente a string.printable (respuesta de @jterrace), excepto por la ausencia de devoluciones y tabulaciones (‘\ t’, ‘\ n’, ‘\ x0b’, ‘\ x0c’ y ‘\ r’) pero no corresponde al rango de tu pregunta

Trabajando a través de Fluent Python (Ramalho) – muy recomendable. Enumere la comprensión one-ish-liners inspirada en el Capítulo 2:

 onlyascii = ''.join([s for s in data if ord(s) < 127]) onlymatch = ''.join([s for s in data if s in 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'])