【问题标题】:Python Read String from File with Strange EncodingPython从具有奇怪编码的文件中读取字符串
【发布时间】:2016-04-07 15:36:04
【问题描述】:

我做了一个猪拉丁语翻译器,它接收用户的输入,翻译它,然后返回它。我想添加输入文本文件以从中获取文本的功能,但我遇到了文件未按预期打开的问题。 这是我的代码:

from sys import argv
script, filename = argv

file = open(filename, "r")

sentence = file.read()

print sentence

file.close()

问题是当我打印出文件中的信息时,它看起来像这样:

■T h i s   i s   s o m e   t e x t   i n   a   f i l e

而不是这个:

This is some text in a file

我知道我可以通过切片来解决空格和奇怪的方形字符,但我觉得这是一种症状,我想了解为什么文本的格式很奇怪,所以也许我可以解决这个原因。

【问题讨论】:

  • 嘿,所以我的回答可以更准确一点,您可以编辑您的帖子并从命令行输入hexdump <filename>file <filename> 的结果吗?假设您不在 Windows 上。
  • 或者至少告诉我们你用来制作那个文本文件的程序。
  • 我用的是记事本++。至于做 hexdump,我回家后会做。
  • 我尝试执行 hexdump ,它说命令 hexdump 无法识别。文件也是如此。
  • @Supetorus: hexdumpfile 是类 Unix 系统上的标准命令,这就是为什么 Will 说“假设你 不是在 Windows 上”。

标签: python string character-encoding file-handling


【解决方案1】:

起初,当我看到每个人都回答有关 unicode 和 utf 的内容时,我回避阅读并尝试修复它,但我坚持学习 Python 编程,所以我做了一些研究,主要是这个网站。 The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)

这真的很有帮助。所以我能收集到的是我用来写文本文件的notepad++,用UTF-8写的,python用UTF-16读的。解决方案是导入编解码器,并像这样使用编解码器功能(正如威尔上面所说): 从系统导入 argv 导入编解码器

script, filename = argv

file = codecs.open(filename, encoding = "utf-8")

sentence = file.read()

print sentence

file.close()

【讨论】:

  • 很奇怪。 UTF-8 不应为 ASCII 范围内的字符生成这些空格。但无论如何...除了 SO 联合创始人 Joel 的那篇文章,您可能还想看看 SO 资深人士 Ned Batchelder 的 unipain,它更特定于 Python。
【解决方案2】:

我相信这是一个 Unicode UTF-16 编码文件,这是“Unicode Byte Order Mark”(BOM)。它也可能是另一种带有字节顺序标记的编码,但它肯定看起来是一种多字节编码。

这也是您在字符之间看到空格的原因。 UTF-16 有效地将每个字符表示为两个字节,但对于您使用的标准 ASCII 字符,另一半字符为空(第二个字节为 0)。

试试这个:

from sys import argv
import codecs
script, filename = argv

file = codecs.open(filename, encoding='utf-16')
sentence = file.read()
print sentence
file.close()

encoding='utf-16' 替换为实际的任何编码。您可能只需要尝试一些并进行试验。

【讨论】:

  • 错字:字符的另一半为零。您的答案看起来不错,可惜 OP 没有响应。
  • 谢谢!已更正:) 是的,我希望 OP 可以显示hexdump <file>file <file> 的输出,这样我们就可以更清楚地弄清楚编码是什么。我认为 SO 将其转换为 UTF-8,并且在我结束时对其进行十六进制转储不会显示任何已知的字节顺序标记。
  • 啊哈。我检查了我的记事本++ 设置,它以 UTF-8 格式创建文件。我使用编解码器的东西来修复它并且它有效。我还尝试使用 hexdump 和文件,因为我在上面的评论中告诉另一个人,他们都说命令无法识别。也许我没有按照你的意思使用它。我将它直接输入到 powershell 中,因为hexdump text.txt text.txt 是我的文件名。与文件相同。
【解决方案3】:

原始文件是 UTF-16。这是一个写入 UTF-16 文件并使用 openio.open 读取的示例,它采用编码参数:

#!python2
import io

sentence = u'This is some text in a file'

with io.open('file.txt','w',encoding='utf16') as f:
    f.write(sentence)

with open('file.txt') as f:
    print f.read()

with io.open('file.txt','r',encoding='utf16') as f:
    print f.read()

在美国 Windows 7 控制台上的输出:

 ■T h i s   i s   s o m e   t e x t   i n   a   f i l e
This is some text in a file

作为猜测,我会说 OP 在 Windows 记事本中创建了文本文件并将其保存为“Unicode”,这是微软对 UTF-16 编码的误称。

【讨论】:

  • 很好的答案!让我感到困惑的是,当我尝试从帖子文本中hexdump BOM 时,它似乎不是 UTF-16 BOM。但我猜这只是因为 SO 使用 UTF-8 :)
  • @Will,帖子文本很可能在cp437 中解码,因为这就是我的终端,并且该编码中的 ■ 字符是 FEh。这是 UTF-16 BOM 的一部分 :)
【解决方案4】:

嗯 - 最引人注目的解释是您的文件正在正确读取数据。

至于为什么会有奇怪的输出 - 可能是由于多种原因

但是看起来您使用的是 Python 2(打印语句)- 并且文本显示为

CHARCHAR

我会假设您正在阅读的文件是 UNICODE 编码文本 - 所以 ABC 是 witten \u0065\u0066\u0067

要么解码字节字符串 - 直到 Unicode 字符串 - 要么使用 Python 3 并查看 Unicode 问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-07
    • 1970-01-01
    • 1970-01-01
    • 2012-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多