如何恢复破碎的字符串到unicode的字符串?

时间:2014-10-01 15:39:46

标签: python perl encoding utf-8 character-encoding

我有一个字符串(实际上是文件名),如:ноÑÑажнаÑ。它是破碎的联想NAS和samba配置的遗产。

enca报道: 通用转换格式8位; UTF-8   从ISO-8859-5双重编码为​​UTF-8

如何使用perl / shell / python恢复字符串(文件名)?

3 个答案:

答案 0 :(得分:3)

你必须改变这个过程。在Python中,您可以将Unicode值编码为Latin-1以再次获得一对一的字节,因此该过程将是:

  • 从UTF-8解码为Unicode
  • 从Unicode编码到Latin-1
  • 再次从UTF-8解码为Unicode
  • 编码为ISO-8859-5

您的错位文本缺少无法打印的字符。如果我忽略了破碎的字符,我得到:

>>> 'ноÑÑажнаÑ.'.decode('utf8').encode('latin1').decode('utf8', 'ignore').encode('iso8859_5')
'\xdd\xde\xd0\xd6\xdd\xd0.'

在编码之前将结果打印到ISO-8858-5,但用占位符替换损坏的字符:

>>> print 'ноÑÑажнаÑ.'.decode('utf8').encode('latin1').decode('utf8', 'replace')
но��ажна�.

答案 1 :(得分:0)

我有一个非常类似的问题,根据enca -L ru broken-file.txt输出判断:

Universal transformation format 8 bits; UTF-8
  Surrounded by/intermixed with non-text data
  Doubly-encoded to UTF-8 from ISO-8859-5

上面的答案没有解决问题,所以我尝试了以下变化:

def decode(contents):
    u = contents.decode("utf-8")
    d = u.encode("raw_unicode_escape")
    return d.decode("cp1251")

# Can be used like:
decode(open('broken-file.txt', "b").read())

请注意,在我的情况下,enca提供了错误信息:我将ISO-8859-5替换为Windows-1251,因为前者几乎没有在任何地方使用过。另外,使用raw_unicode_escape代替latin-1,赞成Decoding double encoded utf8 in Python

答案 2 :(得分:0)

我不确定此文本是否可挽救,但作为通用答案,有一个名为 ftfy 的出色 Python 包,它尝试恢复格式错误的文本并可以解释其处理过程。

基本的 CLI 用法如下所示:

$ echo "ноÑÑажнаÑ" | ftfy
ноÑÑажнаÑ
$ echo "ноÑÑажнаÑ" | ftfy -e iso-8859-5
УТНУТОУ'У'УТАУТЖУТНУТАУ'

我已经像这样成功地将它与其他输入一起使用了:

$ echo 'Juan Cañas' | ftfy
Juan Cañas

使用 Python API,您可以获得解释并处理它们:

>>> ftfy.fix_and_explain('Juan Cañas')
ExplainedText(text='Juan Cañas', explanation=[('encode', 'sloppy-windows-1252'), ('decode', 'utf-8'), ('normalize', 'NFC')])