texto separar quitar por limpiar especiales espacios eliminar caracteres caracter cadenas acentos python unicode encoding ascii

separar - string en python



Reemplazar caracteres que no sean ASCII con un solo espacio (6)

Necesito reemplazar todos los caracteres que no sean ASCII (/ x00- / x7F) con un espacio. Me sorprende que esto no sea nada fácil en Python, a menos que me falte algo. La siguiente función simplemente elimina todos los caracteres que no son ASCII:

def remove_non_ascii_1(text): return ''''.join(i for i in text if ord(i)<128)

Y este reemplaza los caracteres no ASCII con la cantidad de espacios según la cantidad de bytes en el punto de código del carácter (es decir, el carácter se reemplaza por 3 espacios):

def remove_non_ascii_2(text): return re.sub(r''[^/x00-/x7F]'','' '', text)

¿Cómo puedo reemplazar todos los caracteres no ASCII con un solo espacio?

Of the myriad of questions SO similar , none replacement character address as opposed to stripping , and además se dirige a todos los caracteres no ascii que no tienen un carácter específico.


¿Qué hay de este?

def replace_trash(unicode_string): for i in range(0, len(unicode_string)): try: unicode_string[i].encode("ascii") except: #means it''s non-ASCII unicode_string=unicode_string[i].replace(" ") #replacing it with a single space return unicode_string


Como enfoque nativo y eficiente, no es necesario utilizar ord o cualquier loop sobre los caracteres. Simplemente codifica con ascii e ignora los errores.

Lo siguiente simplemente eliminará los caracteres no ascii:

new_string = old_string.encode(''ascii'',errors=''ignore'')

Ahora, si desea reemplazar los caracteres eliminados solo haga lo siguiente:

final_string = new_string + b'' '' * (len(old_string) - len(new_string))


Para el procesamiento de caracteres , use cadenas Unicode:

PythonWin 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:57:17) [MSC v.1600 64 bit (AMD64)] on win32. >>> s=''ABC马克def'' >>> import re >>> re.sub(r''[^/x00-/x7f]'',r'' '',s) # Each char is a Unicode codepoint. ''ABC def'' >>> b = s.encode(''utf8'') >>> re.sub(rb''[^/x00-/x7f]'',rb'' '',b) # Each char is a 3-byte UTF-8 sequence. b''ABC def''

Pero tenga en cuenta que aún tendrá un problema si su cadena contiene caracteres Unicode descompuestos (carácter separado y combinación de acentos, por ejemplo):

>>> s = ''mañana'' >>> len(s) 6 >>> import unicodedata as ud >>> n=ud.normalize(''NFD'',s) >>> n ''mañana'' >>> len(n) 7 >>> re.sub(r''[^/x00-/x7f]'',r'' '',s) # single codepoint ''ma ana'' >>> re.sub(r''[^/x00-/x7f]'',r'' '',n) # only combining mark replaced ''man ana''


Para usted, obtenga la representación más parecida de su cadena original. Recomiendo el módulo unidecode :

from unidecode import unidecode def remove_non_ascii(text): return unidecode(unicode(text, encoding = "utf-8"))

Entonces puedes usarlo en una cadena:

remove_non_ascii("Ceñía") Cenia


Si el personaje de reemplazo puede ser ''?'' en lugar de un espacio, sugeriría result = text.encode(''ascii'', ''replace'').decode() :

"""Test the performance of different non-ASCII replacement methods.""" import re from timeit import timeit # 10_000 is typical in the project that I''m working on and most of the text # is going to be non-ASCII. text = ''Æ'' * 10_000 print(timeit( """ result = ''''.join([c if ord(c) < 128 else ''?'' for c in text]) """, number=1000, globals=globals(), )) print(timeit( """ result = text.encode(''ascii'', ''replace'').decode() """, number=1000, globals=globals(), ))

Resultados:

0.7208260721400134 0.009975979187503592


Su expresión ''''.join() está filtrando , eliminando todo lo que no sea ASCII; podrías usar una expresión condicional en su lugar:

return ''''.join([i if ord(i) < 128 else '' '' for i in text])

Esto maneja los caracteres uno por uno y todavía usaría un espacio por personaje reemplazado.

Su expresión regular debería reemplazar a los caracteres no ASCII consecutivos con un espacio:

re.sub(r''[^/x00-/x7F]+'','' '', text)

Tenga en cuenta el + allí.