gpt4 book ai didi

python-2.7 - 从 python I/O 输出到文件的 Unicode 字符

转载 作者:行者123 更新时间:2023-12-02 00:57:01 25 4
gpt4 key购买 nike

我不知道这是我对 UTF-8 还是对 python 的误解,但我很难理解 python 如何将 Unicode 字符写入文件。顺便说一句,我在 OSX 下的 Mac 上,如果这有什么不同的话。

假设我有以下 unicode 字符串

foo=u'\x93smartquotes\x94\n'中的东西

这里的\x93 和\x94 是那些糟糕的智能引号。

然后我将它写入一个文件:

以 open('file.txt','w') 作为文件:
file.write(foo.encode('utf8'))

当我在文本编辑器(如 TextWrangler)或网络浏览器中打开文件时,file.txt 看起来像是写成

\xc2\x93**Stuff in smartquotes\xc2\x94\n

文本编辑器正确地将文件理解为 UTF8 编码,但它将\xc2\x93 呈现为垃圾。如果我进入并手动删除\xc2 部分,我会得到我期望的结果,TextWrangler 和 Firefox 将 utf 字符呈现为智能引号。

这正是我将文件读回 python 而不将其解码为“utf8”时得到的结果。但是,当我使用 read().decode('utf8') 方法读取它时,我得到了我最初输入的内容,没有\xc2 位。

这让我抓狂,因为我正在尝试将一堆 html 文件解析为文本,而这些 un​​icode 字符的错误呈现搞砸了一堆东西。

我也在 python3 中正常使用读/写方法进行了尝试,它具有相同的行为。

编辑:关于手动删除\xc2,事实证明当我这样做时它呈现正确,因为浏览器和文本编辑器默认为拉丁编码。

另外,作为后续,Filefox 将文本呈现为

☐Stuff in smartquotes☐

其中框是空的 unicode 值,而 Chrome 将文本呈现为

Stuff in smartquotes

最佳答案

问题是,u'\x93'u'\x94' 不是智能引号的 Unicode 代码点。它们是 Windows-1252 中的智能引号编码,与 latin1 不同编码。在 latin1 中,这些值未定义。

>>> import unicodedata as ud
>>> ud.name(u'\x93')
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
ValueError: no such name
>>> import unicodedata as ud
>>> ud.name(u'\x94')
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
ValueError: no such name
>>> ud.name(u'\u201c')
'LEFT DOUBLE QUOTATION MARK'
>>> ud.name(u'\u201d')
'RIGHT DOUBLE QUOTATION MARK'

所以你应该:

foo = u'\u201cStuff in smartquotes\u201d'
foo = u'\N{LEFT DOUBLE QUOTATION MARK}Stuff in smartquotes\N{RIGHT DOUBLE QUOTATION MARK}'

或在 UTF-8 源文件中:

#coding:utf8
foo = u'“Stuff in smartquotes”'

编辑:如果您的 Unicode 字符串中包含那些不正确的字节,可以通过以下方法修复它们。前 256 个 Unicode 代码点与 latin1 编码 1:1 映射,因此它可用于将错误解码的 Unicode 字符串直接编码回字节字符串,以便使用正确的解码:

>>> foo = u'\x93Stuff in smartquotes\x94'
>>> foo
'\x93Stuff in smartquotes\x94'
>>> foo.encode('latin1').decode('windows-1252')
'\u201cStuff in smartquotes\u201d'
>>> print foo
“Stuff in smartquotes”

如果您有错误 Unicode 字符的 UTF-8 编码版本:

>>> foo = '\xc2\x93Stuff in smartquotes\xc2\x94'
>>> foo = foo.decode('utf8').encode('latin1').decode('windows-1252')
>>> foo
u'\u201cStuff in smartquotes\u201d'
>>> print foo
“Stuff in smartquotes”

如果遇到最坏的情况,则使用以下 Unicode 字符串:

>>> foo = u'\xc2\x93Stuff in smartquotes\xc2\x94'
>>> foo.encode('latin1') # back to a UTF-8 encoded byte string.
'\xc2\x93Stuff in smartquotes\xc2\x94'
>>> foo.encode('latin1').decode('utf8') # Undo the UTF-8, but Unicode is still wrong.
u'\x93Stuff in smartquotes\x94'
>>> foo.encode('latin1').decode('utf8').encode('latin1') # back to a byte string.
'\x93Stuff in smartquotes\x94'
>>> foo.encode('latin1').decode('utf8').encode('latin1').decode('windows-1252') # Now decode correctly.
u'\u201cStuff in smartquotes\u201d'

关于python-2.7 - 从 python I/O 输出到文件的 Unicode 字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33578586/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com