【发布时间】:2010-05-03 14:54:44
【问题描述】:
我需要将一些非 ASCII 字符更改为“_”。 例如,
Tannh‰user -> Tannh_user- 如果我在 Python 中使用正则表达式,我该怎么做?
- 不使用 RE 有没有更好的方法来做到这一点?
【问题讨论】:
我需要将一些非 ASCII 字符更改为“_”。 例如,
Tannh‰user -> Tannh_user【问题讨论】:
re.sub(r'[^\x00-\x7F]', '_', theString)
如果字符串是 unicode,或者 ASCII 占用值 0 到 0x7F(latin-1、UTF-8 等)的编码字符串,这将起作用。
【讨论】:
回答问题
'[\u0080-\uFFFF]'
将匹配任何不在前 128 个字符范围内的 UTF-8 字符
re.sub('[\u0080-\uFFFF]+', '_', x)
将用下划线替换任何连续的非ASCII字符序列
【讨论】:
使用神奇的正则表达式[ -~] 可以解决它:
import re
re.sub(r"[^ -~]", "_", "Tannh‰user")
# 'Tannh_user'
解释:
[ -~] 捕获所有 ascii 字符^我们可以捕获所有非ascii字符【讨论】:
针对 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、拉丁文和其他一些编码中的 str :
>>> s = 'Tannh‰user' # or u'Tannh‰user' in Python 2
>>>
>>> ''.join(c if ord(c) < 128 else '_' for c in s)
'Tannh_user'
【讨论】:
使用 Python 对字符编码的支持:
# coding: utf8
import codecs
def underscorereplace_errors(exc):
return (u'_', exc.end)
codecs.register_error('underscorereplace', underscorereplace_errors)
print u'Tannh‰user'.encode('ascii', 'underscorereplace')
【讨论】:
我宁愿只在字符串中的每个字符上调用 ord,1 比 1。如果 ord([char]) >= 128 字符不是 ascii 字符,应该被替换。
【讨论】:
如果您知道要替换哪些字符,则可以应用字符串方法
mystring.replace('oldchar', 'newchar')
【讨论】:
ord(item)>127。然后,想想你的代码对这个字符串做了什么:'\xa0'*1000.
'\xa0'*1000 示例中,您的代码执行了整个mystring 替换一千次,其中999 次是不必要的。如果你不同意这一点,那么给定astr='hello'; c=0,在这个循环之后c 的值是多少:for char in astr: c+= 1; astr=''?我说是 5,你可能认为是 1。