Character reading from file in Python

在文本文件中,有一个字符串“ I don’t like this”。

但是,当我把它读入一个字符串时,它就变成了“我不像这样 xe2 x80 x98t”。我知道 u2018是“’”的 Unicode 表示。我吸毒

f1 = open (file1, "r")
text = f1.read()

命令进行阅读。

现在,是否有可能以这样的方式读取字符串,当它被读入字符串时,它是“ I don’t like this”,而不是“ I don xe2 x80 x98t like this”?

第二次编辑: 我看到一些人使用映射来解决这个问题,但是真的没有内置的转换来做这种 ANSI 到 unicode (反之亦然)的转换吗?

277432 次浏览

实际上,U + 2018是特殊字符‘的 Unicode 表示形式。如果需要,可以使用以下代码将该字符的实例转换为 U + 0027:

text = text.replace (u"\u2018", "'")

另外,您使用什么来写文件? f1.read()应该返回一个类似如下的字符串:

'I don\xe2\x80\x98t like this'

If it's returning this string, the file is being written incorrectly:

'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
with codecs.open('unicode.rst', encoding='utf-8') as f:
for line in f:
print repr(line)

也可以在更新模式下打开文件,允许读写:

with codecs.open('test', encoding='utf-8', mode='w+') as f:
f.write(u'\u4500 blah blah blah\n')
f.seek(0)
print repr(f.readline()[:1])

EDIT : 我假设您的预期目标仅仅是能够在 Python 中将文件正确地读入字符串。如果您试图从 Unicode 转换为 ASCII 字符串,那么实际上没有直接的方法,因为 Unicode 字符不一定存在于 ASCII 中。

如果要转换为 ASCII 字符串,请尝试下列操作之一:

  1. 如果您只想处理一些特殊的情况,比如这个特殊的例子,那么可以用 ASCII 等价物替换特定的 unicode 字符

  2. 使用 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,您可能需要保留一个 unicode 标点符号的映射,以便将其转换为 ASCII。

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。

你必须搜索“ 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                                     '.

还可以使用 python3 read 方法读取编码的文本文件:

f = open (file.txt, 'r', encoding='utf-8')
text = f.read()
f.close()

有了这个变体,就不需要导入任何其他库了

不确定是否使用(error = “忽略”)选项,但它似乎适用于具有奇怪 Unicode 字符的文件。

with open(fName, "rb") as fData:
lines = fData.read().splitlines()
lines = [line.decode("utf-8", errors="ignore") for line in lines]