用一个空格replace非ASCII字符

我需要用空格replace所有非ASCII(\ x00- \ x7F)字符。 我很惊讶,这不是在python死容易,除非我失去了一些东西。 以下function只是删除所有非ASCII字符:

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

而这个字符代码点中的字节数(即字符被replace为3个空格)用空格的数量replace非ASCII字符:

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

我怎样才能用一个空格replace所有的非ASCII字符?

在 大量 类似的 SO 问题中 , 没有一个 解决了 与 剥离 相反的 字符 replace 问题 ,另外还解决了所有非ASCII字符不是特定字符的问题。

你的''.join()expression式是过滤 ,删除任何非ASCII; 你可以使用一个条件expression式来代替:

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

这将逐个处理字符,并且每个字符仍将使用一个空格replace。

你的正则expression式应该用一个空格replace连续的非ASCII字符:

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

注意在那里。

对你来说,得到你最初的string最相似的表示,我build议:

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

那么你可以在一个string中使用它:

 remove_non_ascii("Ceñía") Cenia 

对于字符处理,请使用Unicodestring:

 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' 

但是请注意,如果string包含分解的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' 

这个如何?

 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 

如果replace字符可以是'?' 而不是一个空格,那么我会build议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(), )) 

结果:

 0.7208260721400134 0.009975979187503592