使用Python unicode时的特殊字符问题
#!/usr/bin/env python
# -*- coding: utf_8 -*-
def splitParagraphIntoSentences(paragraph):
''' break a paragraph into sentences
and return a list '''
import re
# to split by multile characters
# regular expressions are easiest (and fastest)
sentenceEnders = re.compile('[.!?][\s]{1,2}(?=[A-Z])')
sentenceList = sentenceEnders.split(paragraph, re.UNICODE)
return sentenceList
if __name__ == '__main__':
p = "While other species (e.g. horse mango, M. foetida) are also grown ,Mangifera indica – the common mango or Indian mango – Sheffield’s only mango tree is valued at £9.2 billion."
sentences = splitParagraphIntoSentences(p)
for s in sentences:
print s.strip()
预期的输出: 虽然其他种类(比如马芒果,M. foetida)也被种植,但Mangifera indica——普通芒果或印度芒果——谢菲尔德唯一的芒果树价值92亿英镑。
实际输出: 虽然其他种类(比如马芒果,M. foetida)也被种植,但Mangifera ind ica ΓÇô 普通芒果或印度芒果 ΓÇô 谢菲尔德ΓÇÖ唯一的芒果树价值 ┬ú92亿英镑。
这里不需要关注句子的意思,主要问题是它无法正确显示一些特殊字符,比如 " - "、" £ "、" ’ " 等等。我尝试过设置sitecustomize.py文件,并用其他编码方式,比如ascii、utf-32、cp-500、iso8859_15和utf-8,但还是没能解决。抱歉,我对python还很陌生。提前谢谢大家的帮助。
4 个回答
这看起来像是 cp437 编码。你可以试试这个:
import codecs, sys
sys.stdout = codecs.getwriter('UTF-8')(sys.stdout)
print u"valued at £9.2 billion."
在 Python 2.6 中,这个方法对我有效。
正如Nam所建议的,使用Unicode字符串字面量是正确的,但如果你的终端使用的是cp437编码,那么它可能无法显示你想用的一些Unicode字符。Windows控制台不支持UTF-8编码,如果你在源文件中声明了coding: utf-8
1,而且没有使用Unicode字面量,那么你发送的就是UTF-8编码。
coding: utf-8
是用来声明你的源文件的编码方式,所以一定要确保你保存的源文件是UTF-8编码。
当你使用Unicode字面量时,Python会按照声明的编码来解释源字符串,并将其转换为Unicode字符串。在打印Unicode字符串时,Python会根据终端的编码来编码这个字符串,如果没有终端编码,就会使用Python 2的默认编码ascii
。
举个例子:
# coding: utf8
print '£9.2 billion' # Sends UTF-8 to cp437 terminal (gibberish)
print u'£9.2 billion' # Correctly prints on cp437 terminal.
print 'Sheffield’s' # Sends UTF-8 to cp437 terminal (gibberish)
# Replaces Unicode characters that are unsupported in cp437.
print u'Sheffield’s £9.2 billion'.encode('cp437','xmlcharrefreplace')
print u'Sheffield’s' # UnicodeEncodeError.
输出结果
£9.2 billion
£9.2 billion
SheffieldΓÇÖs
Sheffield’s £9.2 billion
Traceback (most recent call last):
File "C:\Documents and Settings\metolone\Desktop\x.py", line 10, in <module>
print u'SheffieldΓÇÖs' # UnicodeEncodeError.
File "C:\dev\python27\lib\encodings\cp437.py", line 12, in encode
return codecs.charmap_encode(input,errors,encoding_map)
UnicodeEncodeError: 'charmap' codec can't encode character u'\u2019' in position 9: character maps to <undefined>
所以,不要指望在Windows控制台上所有的Unicode字符都能正确打印。使用支持UTF-8的Python IDE,比如PythonWin(可以在pywin32扩展中找到)。
要在Windows控制台中正确显示Unicode字符,你需要两个东西:一种能够映射你想显示的Unicode字符的编码,以及一种支持这些字符正确图形的字体。对于你的例子,如果你将控制台的代码页改为Windows-1252(chcp 1252
),并将控制台字体改为Consolas或Lucida Console,而不是Raster Fonts,那么如果你使用Unicode字面量(p = u"..."
),你的原始程序就能正常工作。
我找到了这个问题的解决办法。
下面这段代码,运行得很好。
p = p.encode('utf-8') if isinstance(p,unicode) else p