115

在文本文件中,有一个字符串“我不喜欢这个”。

然而,当我把它读成一个字符串时,它变成了“我不喜欢这样\xe2\x80\x98t”。我知道 \u2018 是“'”的 unicode 表示。我用

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

命令进行阅读。

现在,是否有可能以这样的方式读取字符串,当它被读入字符串时,它是“我不喜欢这个”,而不是“我不喜欢这个”?

第二次编辑:我看到有人使用映射来解决这个问题,但实际上,没有内置的转换可以将这种 ANSI 转换为 unicode(反之亦然)吗?

4

9 回答 9

180

参考: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])

编辑:我假设您的预期目标只是能够将文件正确读入 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'
    
于 2008-09-29T06:55:23.980 回答
15

有几点需要考虑。

\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函数而不是 just 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
于 2008-09-29T07:15:17.630 回答
11

也可以使用 python 3 读取方法读取编码的文本文件:

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

有了这个变体,就不需要导入任何额外的库

于 2018-11-29T22:40:27.287 回答
6

但它确实是“我不喜欢这个”而不是“我不喜欢这个”。字符 u'\u2018' 是一个与 "'" 完全不同的字符(并且,在视觉上,应该更多地对应于 '`')。

如果您尝试将编码的 unicode 转换为纯 ASCII,您也许可以保留一个您想要转换为 ASCII 的 unicode 标点符号的映射。

punctuation = {
  u'\u2018': "'",
  u'\u2019': "'",
}
for src, dest in punctuation.iteritems():
  text = text.replace(src, dest)

但是,在 unicode中有很多标点符号,但我想您只能指望其中的几个实际上被创建您正在阅读的文档的任何应用程序使用。

于 2008-09-29T07:00:40.660 回答
3

有可能你有一个带有 unicode 转义字符的非 unicode 字符串,例如:

>>> print repr(text)
'I don\\u2018t like this'

这实际上发生在我身上一次。您可以使用unicode_escape编解码器将字符串解码为 un​​icode,然后将其编码为您想要的任何格式:

>>> uni = text.decode('unicode_escape')
>>> print type(uni)
<type 'unicode'>
>>> print uni.encode('utf-8')
I don‘t like this
于 2008-09-29T07:22:21.233 回答
3

撇开您的文本文件损坏(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                                     '.
于 2008-09-30T20:10:54.873 回答
1

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

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

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

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

如果它返回字符串,则文件写入不正确:

'I don\u2018t like this'
于 2008-09-29T06:52:53.037 回答
1

这是 Python 向您展示 unicode 编码字符串的方式。但我认为您应该能够在屏幕上打印字符串或将其写入新文件而不会出现任何问题。

>>> test = u"I don\u2018t like this"
>>> test
u'I don\u2018t like this'
>>> print test
I don‘t like this
于 2008-09-29T06:54:22.627 回答
1

不确定 (errors="ignore") 选项,但它似乎适用于具有奇怪 Unicode 字符的文件。

with open(fName, "rb") as fData:
    lines = fData.read().splitlines()
    lines = [line.decode("utf-8", errors="ignore") for line in lines]
于 2021-01-02T16:38:52.890 回答