微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 iconv 或 python3 将 utf-8 重新编码为 Latin-1 (ISO-8859-1) 保留重音字符

如何解决使用 iconv 或 python3 将 utf-8 重新编码为 Latin-1 (ISO-8859-1) 保留重音字符

大多数情况下,应该能够更改 UTF-8 的编码 通过简单的 iconv 调用文件转换为 Latin-1 (ISO-8859-1) 编码,例如:

 iconv -c -f  utf-8 -t ISO-8859-1//TRANSLIT

然而,这无法正确处理重音字符。考虑 例如:

$ echo $LC_ALL
C
$ cat Gonzalez.txt 
González,M.
$ file Gonzalez.txt
Gonzalez.txt: UTF-8 Unicode text
$ iconv -c -f  utf-8 -t ISO-8859-1//TRANSLIT < Gonzalez.txt > out
$ file out
out: ASCII text
$ cat out
Gonzalez,M.

我尝试了上述的各种变体,但没有一个正确处理 带重音的“a”,重点是 Latin-1 确实有带重音的“a”。

确实,uconv 确实正确处理了这种情况:

$ uconv -x Any-Accents -f utf-8 -t l1 < Gonzalez.txt > out
$ file out
out: ISO-8859 text

在 emacs 中打开文件或 Sublime 正确显示了带重音的“a”。同样的事情使用 -x nfc

不幸的是,我的目标环境不允许使用“uconv”的解决方案, 所以我正在寻找一个使用 iconv 或 python3 的简单解决方案。

python3 尝试

到目前为止,我尝试使用 python3 还没有成功。 例如,以下内容

import sys
import fileinput  # allows file to be specified or else reads from STDIN

for line in fileinput.input():
    l=line.encode("latin-1","replace") 
    sys.stdout.buffer.write(l) 

产生:

Gonza?lez,M.

(这是一个字面意思的“?”。)

我尝试了各种其他的 python3 可能性,但都没有成功。

请注意,我已经查看了许多关于此主题的 SO 问题,但使用 iconv 或 python3 的答案无法正确处理 Gonzalez.txt。

解决方法

有两种方法可以在 Unicode 中对 A WITH ACUTE ACCENT 进行编码。

一种是使用组合字符,如下面的 Python 内置 ascii 函数所示:

>>> ascii('á')
"'\\xe1'"

但您也可以在无重音字母 a 后使用组合重音符号:

>>> ascii('á')
"'a\\u0301'"

根据显示的应用程序,这两种变体可能看起来无法区分(在我的终端中,后者看起来有点奇怪,因为重音太大了)。

现在,Latin-1 有一个带重音的字母 a,但没有组合重音,所以这就是为什么在用 errors="replace" 编码时,尖音变成问号的原因。

幸运的是,您可以在两种变体之间自动切换。 不赘述(这里有很多的细节),Unicode定义了两种规范化形式,称为composeddecomposed,分别缩写为NFC和NFD . 在 Python 中,您可以使用标准库模块 unicodedata:

>>> import unicodedata as ud
>>> ascii(ud.normalize('NFD','á'))
"'a\\u0301'"
>>> ascii(ud.normalize('NFC','á'))
"'\\xe1'"

在您的具体情况下,您可以将输入字符串转换为 NFC 形式,这将增加拉丁 1 字符的覆盖范围:

>>> n = 'Gonza\u0301lez,M.'
>>> print(n)
González,M.
>>> n.encode('latin1',errors='replace')
b'Gonza?lez,M.'
>>> ud.normalize('NFC',n).encode('latin1',errors='replace')
b'Gonz\xe1lez,M.'

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。