用Python从文件中读取字符
在文本文件中,有一个字符串"我不喜欢这样"。
但是,当我将其读取为字符串时,它变成"我不这样\ xe2 \ x80 \ x98t"。我了解\ u2018是"'"的Unicode表示形式。我用
f1 = open (file1, "r") text = f1.read()
命令来做阅读。
现在,是否可以以这样的方式读取字符串,即当将其读入字符串时,它是"我不喜欢这样",而不是"我不喜欢这样"
第二编辑:我见过有人使用映射解决此问题,但实际上,没有内置的转换可以将这种ANSI转换为unicode(反之亦然)吗?
解决方案
实际上,U + 2018是特殊字符的Unicode表示形式。如果需要,可以使用以下代码将该字符的实例转换为U + 0027:
text = text.replace (u"\u2018", "'")
另外,我们用什么来写文件? f1.read()应该返回一个看起来像这样的字符串:
'I don\xe2\x80\x98t like this'
如果返回此字符串,则表示文件编写不正确:
'I don\u2018t like this'
这是Python的方法,向我们显示unicode编码的字符串。但我认为我们应该能够在屏幕上打印字符串或者将其写入新文件而不会出现任何问题。
>>> test = u"I don\u2018t like this" >>> test u'I don\u2018t like this' >>> print test I don‘t like this
参考:http://docs.python.org/howto/unicode
因此,从文件读取Unicode很简单:
import codecs f = codecs.open('unicode.rst', encoding='utf-8') for line in f: print repr(line)
也可以在更新模式下打开文件,从而允许读取和写入:
f = codecs.open('test', encoding='utf-8', mode='w+') f.write(u'\u4500 blah blah blah\n') f.seek(0) print repr(f.readline()[:1]) f.close()
编辑:我假设预期目标只是为了能够将文件正确读取为Python中的字符串。如果我们要尝试从Unicode转换为ASCII字符串,那么实际上没有直接的方法,因为Unicode字符不一定存在于ASCII中。
如果我们尝试转换为ASCII字符串,请尝试以下操作之一:
- 如果我们只想处理一些特殊情况(例如此特定示例),请使用ASCII等价的方式替换特定的unicode字符。
- 使用
unicodedata
模块的normalize()
和string.encode()
方法可以最大程度地转换为下一个最接近的ASCII等效文本(请参阅https://web.archive.org/web/20090228203858/http ://techxplorer.com/2006/07/18/converting-unicode-to-ascii-using-python):
>>> teststr u'I don\xe2\x80\x98t like this' >>> unicodedata.normalize('NFKD', teststr).encode('ascii', 'ignore') 'I donat like this'
但这确实是"我不喜欢这样"而不是"我不喜欢这样"。字符u'\ u2018'与"'"是完全不同的字符(并且在视觉上应更对应于"`")。
如果我们尝试将编码的unicode转换为纯ASCII,则可能保留要转换为ASCII的unicode标点的映射。
punctuation = { u'\u2018': "'", u'\u2019': "'", } for src, dest in punctuation.iteritems(): text = text.replace(src, dest)
但是,Unicode中有很多标点符号,但是我想我们只能指望其中的几个实际被创建我们正在阅读的文档的应用程序实际使用。
有几点要考虑。
\ u2018字符只能作为Python中unicode字符串表示形式的一部分出现,例如如果我们写:
>>> text = u'‘' >>> print repr(text) u'\u2018'
现在,如果我们只是想简单地打印unicode字符串,只需使用unicode的encode
方法:
>>> text = u'I don\u2018t like this' >>> print text.encode('utf-8') I don‘t like this
为了确保任何文件中的每一行都将被读取为unicode,我们最好使用codecs.open
函数,而不仅仅是open
,它允许我们指定文件的编码:
>>> import codecs >>> f1 = codecs.open(file1, "r", "utf-8") >>> text = f1.read() >>> print type(text) <type 'unicode'> >>> print text.encode('utf-8') I don‘t like this
我们可能会以某种方式拥有带有unicode转义字符的非unicode字符串,例如:
>>> print repr(text) 'I don\u2018t like this'
这实际上发生在我之前。我们可以使用unicode_escape
编解码器将字符串解码为unicode,然后将其编码为所需的任何格式:
>>> uni = text.decode('unicode_escape') >>> print type(uni) <type 'unicode'> >>> print uni.encode('utf-8') I don‘t like this
撇开文本文件已损坏的事实(U + 2018是左引号,而不是撇号):iconv可用于将unicode字符音译为ASCII。
我们必须在Google上搜索" iconvcodec",因为该模块似乎不再受支持,而且我也找不到它的规范主页。
>>> import iconvcodec >>> from locale import setlocale, LC_ALL >>> setlocale(LC_ALL, '') >>> u'\u2018'.encode('ascii//translit') "'"
另外,我们可以使用iconv
命令行实用程序来清理文件:
$ xxd foo 0000000: e280 980a .... $ iconv -t 'ascii//translit' foo | xxd 0000000: 270a '.