我需要用空格替换所有非ascii (\x00-\x7F)字符。我很惊讶,这在Python中不是非常容易的,除非我遗漏了什么。下面的函数简单地删除所有非ascii字符:
def remove_non_ascii_1(text):
return ''.join(i for i in text if ord(i)<128)
这一个替换非ascii字符与空格的数量在字符编码点的字节数(即-字符替换为3个空格):
def remove_non_ascii_2(text):
return re.sub(r'[^\x00-\x7F]',' ', text)
如何用一个空格替换所有非ascii字符?
在无数类似的SO问题中,没有一个是针对字符替换而不是剥离的,另外是针对所有非ascii字符而不是特定字符。
可能是为了一个不同的问题,但我提供了@Alvero的答案(使用unidecode)的我的版本。我想在我的字符串上做一个“常规”剥离,即空白字符的字符串的开始和结束,然后用“常规”空间替换仅其他空白字符,即。
"Ceñíaㅤmañanaㅤㅤㅤㅤ"
to
"Ceñía mañana"
,
def safely_stripped(s: str):
return ' '.join(
stripped for stripped in
(bit.strip() for bit in
''.join((c if unidecode(c) else ' ') for c in s).strip().split())
if stripped)
我们首先将所有非unicode空格替换为常规空格(并再次将其连接),
''.join((c if unidecode(c) else ' ') for c in s)
然后我们再次用python的正常拆分,剥离每个“位”,
(bit.strip() for bit in s.split())
最后将它们重新连接起来,但前提是字符串通过了if测试,
' '.join(stripped for stripped in s if stripped)
correctly returns ' Cenia manana '。
将所有非ascii (\x00-\x7F)字符替换为空格:
''.join(map(lambda x: x if ord(x) in range(0, 128) else ' ', text))
要替换所有可见字符,请尝试以下操作:
import string
''.join(map(lambda x: x if x in string.printable and x not in string.whitespace else ' ', text))
这将给出相同的结果:
''.join(map(lambda x: x if ord(x) in range(32, 128) else ' ', text))
如果替换字符可以是'?'而不是空格,那么我建议result = text。编码(“ascii”、“替换”).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(),
))
结果:
0.7208260721400134
0.009975979187503592
你的" .join()表达式正在过滤,删除任何非ascii的东西;你可以使用条件表达式:
return ''.join([i if ord(i) < 128 else ' ' for i in text])
这将逐个处理字符,并且仍然会使用一个空格替换每个字符。
你的正则表达式应该用空格替换连续的非ascii字符:
re.sub(r'[^\x00-\x7F]+',' ', text)
注意这里的+。