我需要用空格替换所有非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'

其他回答

作为一种原生且高效的方法,您不需要使用ord或任何字符循环。用ascii码编码,忽略错误。

下面只会删除非ascii字符:

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

现在,如果你想替换被删除的字符,只需执行以下操作:

final_string = new_string + b' ' * (len(old_string) - len(new_string))
def filterSpecialChars(strInput):
    result = []
    for character in strInput:
        ordVal = ord(character)
        if ordVal < 0 or ordVal > 127:
            result.append(' ')
        else:
            result.append(character)
    return ''.join(result)

像这样叫它:

result = filterSpecialChars('Ceñía mañana')
print(result)

对于字符处理,使用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'

我的问题是我的字符串包含了像BelgiÃ的België和&#x20AC的€符号。我不想把它们换成空格。但要有正确的符号。

我的解决方案是string.encode('Latin1').decode('utf-8')

将所有非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))