我经常使用包含以下字符的utf-8文本:
\xc2\x99
\xc2\x95
\xc2\x85
等等
这些字符会让我工作中的其他库混淆,所以需要进行替换。
有没有一种更有效的方法来做到这一点,而不是:
text.replace('\xc2\x99', ' ').replace('\xc2\x85, '...')
可以使用正则表达式解决问题;只需在方括号内列出所有有问题的字符即可,例如:
import re
print re.sub(r'[\xc2\x99]'," ","Hello\xc2There\x99")
这将打印出“Hello There ”,并将不需要的字符替换为空格。
或者,如果您有不同的替换字符:
# remove annoying characters
chars = {
'\xc2\x82' : ',', # High code comma
'\xc2\x84' : ',,', # High code double comma
'\xc2\x85' : '...', # Tripple dot
'\xc2\x88' : '^', # High carat
'\xc2\x91' : '\x27', # Forward single quote
'\xc2\x92' : '\x27', # Reverse single quote
'\xc2\x93' : '\x22', # Forward double quote
'\xc2\x94' : '\x22', # Reverse double quote
'\xc2\x95' : ' ',
'\xc2\x96' : '-', # High hyphen
'\xc2\x97' : '--', # Double hyphen
'\xc2\x99' : ' ',
'\xc2\xa0' : ' ',
'\xc2\xa6' : '|', # Split vertical bar
'\xc2\xab' : '<<', # Double less than
'\xc2\xbb' : '>>', # Double greater than
'\xc2\xbc' : '1/4', # one quarter
'\xc2\xbd' : '1/2', # one half
'\xc2\xbe' : '3/4', # three quarters
'\xca\xbf' : '\x27', # c-single quote
'\xcc\xa8' : '', # modifier - under curve
'\xcc\xb1' : '' # modifier - under line
}
def replace_chars(match):
char = match.group(0)
return chars[char]
return re.sub('(' + '|'.join(chars.keys()) + ')', replace_chars, text)
我认为这里存在一个潜在的问题,调查和解决它可能是个好主意,而不只是试图掩盖症状。
\xc2\x95
是字符U+0095(C1控制字符 MESSAGE WAITING)的UTF-8编码。你的库无法处理它并不奇怪,但问题在于,它是如何出现在你的数据中的呢?
很有可能最初它以Windows-1252编码中的0x95字符(BULLET)开始,被错误地解码为U+0095,而不是正确的U+2022,并重新编码为UTF-8。(日本术语mojibake描述了这种错误)。
如果这是正确的,则可以将它们放回到Windows-1252中,然后这次正确地解码成Unicode来恢复原始字符。(在这些示例中,我使用的是Python 3.3;在Python 2中,这些操作略有不同。)
>>> b'\x95'.decode('windows-1252')
'\u2022'
>>> import unicodedata
>>> unicodedata.name(_)
'BULLET'
如果您想对范围为0x80–0x99的所有有效Windows-1252字符进行此更正,可以使用以下方法:
def restore_windows_1252_characters(s):
"""Replace C1 control characters in the Unicode string s by the
characters at the corresponding code points in Windows-1252,
where possible.
"""
import re
def to_windows_1252(match):
try:
return bytes([ord(match.group(0))]).decode('windows-1252')
except UnicodeDecodeError:
# No character at the corresponding code point: remove it.
return ''
return re.sub(r'[\u0080-\u0099]', to_windows_1252, s)
例如:>>> restore_windows_1252_characters('\x95\x99\x85')
'•™…'
如果您想从字符串中删除所有非ASCII字符,可以使用
text.encode("ascii", "ignore")
text
是一个unicode字符串——即以 text=u"..."
的形式定义——如果不是,则会引发 UnicodeDecodeError
错误。 - Nateimport unicodedata
# Convert to unicode
text_to_uncicode = unicode(text, "utf-8")
# Convert back to ascii
text_fixed = unicodedata.normalize('NFKD',text_to_unicode).encode('ascii','ignore')
这些字符不在 ASCII
库中,这就是你遇到错误的原因。
为了避免这些错误,在读取文件时可以采取以下措施。
import codecs
f = codecs.open('file.txt', 'r',encoding='utf-8')
想了解更多关于这种错误的信息,请查看此链接。
这不是“Unicode字符” - 它更像是一个UTF-8编码的字符串。(虽然对于大多数字符,你的前缀应该是\xC3,而不是\xC2)。在95%的情况下,除非你正在与COBOL后端通信,否则你不应该将它们丢弃。你知道,世界不仅限于26个字符。
有一篇简明的文章可以解释Unicode字符串(在Python 2中用作Unicode对象,在Python 3中用作字符串)和这里使用的字符串之间的区别:http://www.joelonsoftware.com/articles/Unicode.html - 请务必阅读。即使您从未计划在所有应用程序中使用英语以外的任何内容,您仍将遇到无法适应7位ASCII的符号,如€或º。那篇文章会帮助你。
话虽如此,也许你正在使用的库接受Unicode Python对象,你可以通过以下方式将你的UTF-8 Python 2字符串转换为Unicode:
var_unicode = var.decode("utf-8")
var_ascii = var_unicode.encode("ascii", "replace")
text.translate(table)
,参考http://docs.python.org/library/stdtypes.html#str.translate - TryPyPystr.maketrans()
。 - JAB