使用Python查找并替换非ASCII字符的正则表达式

8 投票
7 回答
21490 浏览
提问于 2025-04-15 22:17

我需要把一些不是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.encodereplace 时,非 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'

撰写回答