Reemplazar caracteres no ASCII con un solo espacio
Necesito reemplazar todos los caracteres no ASCII (\x00-\x7F) con un espacio. Me sorprende que esto no sea del todo fácil en Python, a menos que me esté perdiendo algo. La siguiente función simplemente elimina todos los caracteres no ASCII:
def remove_non_ascii_1(text):
return ''.join(i for i in text if ord(i)<128)
Y este reemplaza caracteres no ASCII con la cantidad de espacios según la cantidad de bytes en el punto de código de caracteres (es decir, el carácter –
se reemplaza con 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?
De el una miríada de de similar ASÍ preguntas, ninguno dirección carácter reemplazo como se opuso a a pelar, y además de la dirección de todos los caracteres que no son ascii no un carácter específico.
6 answers
Su expresión ''.join()
es filtrando , eliminando cualquier cosa que no sea ASCII; podría usar una expresión condicional en su lugar:
return ''.join([i if ord(i) < 128 else ' ' for i in text])
Esto maneja caracteres uno por uno y todavía usaría un espacio por carácter reemplazado.
Su expresión regular solo debe reemplazar caracteres consecutivos no ASCII con un espacio:
re.sub(r'[^\x00-\x7F]+',' ', text)
Note el +
allí.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-19 18:11:35
Para obtener la representación más similar 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-22 17:58:00
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 todavía tendrá un problema si su cadena contiene caracteres Unicode descompuestos (caracteres separados 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'
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-19 21:26:15
Si el carácter de reemplazo puede ser '?'en lugar de un espacio, entonces yo 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-03 11:12:33
¿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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-20 22:35:18
Como un enfoque nativo y eficiente, no es necesario utilizar ord
o cualquier bucle sobre los caracteres. Simplemente codifique con ascii
e ignore 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, haga lo siguiente:
final_string = new_string + b' ' * (len(old_string) - len(new_string))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-23 14:39:32