使用Python查找并替换非ASCII字符的正则表达式
我需要把一些不是ASCII字符的字符替换成'_'。比如,
Tannh‰user -> Tannh_user
- 如果我用Python的正则表达式,应该怎么做呢?
- 有没有更好的方法,不用正则表达式来实现这个?
7 个回答
9
为了回答这个问题
'[\u0080-\uFFFF]'
这个表达式会匹配任何不是前128个字符的UTF-8字符
re.sub('[\u0080-\uFFFF]+', '_', x)
这个表达式会把连续的非ASCII字符替换成一个下划线
16
re.sub(r'[^\x00-\x7F]', '_', theString)
如果theString是Unicode编码,或者是ASCII值在0到0x7F范围内的字符串(比如latin-1、UTF-8等),那么这个方法就能正常工作。
6
更新为 Python 3:
>>> 'Tannh‰user'.encode().decode('ascii', 'replace').replace(u'\ufffd', '_')
'Tannh___user'
首先,我们使用 encode()
来创建字节字符串 - 默认情况下,它使用 UTF-8 编码。如果你已经有了字节字符串,那就可以跳过这个编码步骤。
接着,我们使用 ascii 编码将其转换为“普通”字符串。
这里利用了 UTF-8 的一个特性:所有非 ASCII 字符都会被编码为值大于等于 0x80 的字节序列。
原始答案 - 针对 Python 2:
如何使用内置的 str.decode
方法来实现:
>>> 'Tannh‰user'.decode('ascii', 'replace').replace(u'\ufffd', '_')
u'Tannh___user'
(你会得到 unicode
字符串,如果需要的话,可以将其转换为 str
。)
你也可以将 unicode
转换为 str
,这样一个非 ASCII 字符就会被替换为 ASCII 字符。但问题是,使用 unicode.encode
和 replace
时,非 ASCII 字符会被转换成 '?'
,所以你无法知道这个问号之前是否就存在;可以参考 Ignacio Vazquez-Abrams 的解决方案。
另一种方法是使用 ord()
函数,比较每个字符的值是否在 ASCII 范围内(0-127) - 这适用于 unicode
字符串以及 utf-8、latin 和其他一些编码下的 str
:
>>> s = 'Tannh‰user' # or u'Tannh‰user' in Python 2
>>>
>>> ''.join(c if ord(c) < 128 else '_' for c in s)
'Tannh_user'