我需要用空格替换所有非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字符而不是特定字符。
对于字符处理,使用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'
但请注意,如果字符串包含分解的Unicode字符(例如,分开的字符和组合的重音标记),仍然会遇到问题:
>>> 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'
你的" .join()表达式正在过滤,删除任何非ascii的东西;你可以使用条件表达式:
return ''.join([i if ord(i) < 128 else ' ' for i in text])
这将逐个处理字符,并且仍然会使用一个空格替换每个字符。
你的正则表达式应该用空格替换连续的非ascii字符:
re.sub(r'[^\x00-\x7F]+',' ', text)
注意这里的+。
对于字符处理,使用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'
但请注意,如果字符串包含分解的Unicode字符(例如,分开的字符和组合的重音标记),仍然会遇到问题:
>>> 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'