【问题标题】:Python 3.5.1 mixed line code file UTF-8 and UTF-16Python 3.5.1 混合行代码文件 UTF-8 和 UTF-16
【发布时间】:2016-06-20 17:34:50
【问题描述】:

我已经成功地解析了我用我写的一个简单的 python 脚本收到的数据文件。我得到的文件是这样的:

file.txt,约 50 列数据,x 1000 行

abcd1,1234a,efgh1,5678a,ijkl1 ...etc 
abcd2,1234b,efgh2,5678b,ijkl2 ...etc
...

不幸的是,有时有些行包含 UTF-16 符号,看起来像这样

abcd1,12341,efgh1,UTF-16 symbols here,ijkl1 ...etc
abcd2,1234b,efgh2,5678b,ijkl2 ...etc
...

我已经能够为我的脚本中的命令实现“latin-1”编码,例如:

open('file fixed.txt', 'w', encoding="latin-1").writelines([line for line in open('file.txt', 'r', encoding="latin-1"])

我的问题在于如下代码:

for line in fileinput.Fileinput('file fixed.txt', inplace=1):
  line = line.replace(":",",")
  print (line, ",")

我无法克服最后一个命令的编码错误。我已尝试强制执行以下编码:

# -*- coding: latin-1 -*-

在文档顶部以及最后提到的命令(查找和替换)之前。如何获取混合编码文件以处理上述命令?我想保留新文件中出现的 UTF-16 (unicode) 符号。提前致谢。

编辑:感谢 Alexis,我能够确定 filinput 不能用于设置另一种编码方法。我使用以下方法解决了我的问题。

f = open(filein,'r', encoding="latin-1")
filedata = f.read()
f.close()

newdata = filedata.replace("old data","new data")

f = open(fileout,'w', encoding="latin-1")
f.write(newdata)
f.close()

【问题讨论】:

  • 拥有一个包含多种不同编码数据的文件是没有意义的。您的文件 all 是 UTF-8 吗?如果没有,您可能需要对其进行一些“手术”,以将所有内容整合到一个编码中。另请注意,没有“UTF-16 符号”之类的东西。您可以使用您喜欢的任何 unicode 编码对 unicode 符号进行编码。
  • (顺便说一句,# -*- coding 在这里是一个红鲱鱼。它只指定你的 Python 源文件的编码;它不会影响你读入的数据文件发生的事情。)跨度>
  • 那么那些“UTF-16 符号”是什么样的呢?你怎么知道那是 UTF-16?

标签: python unicode encoding utf-8 utf-16


【解决方案1】:

您可以告诉fileinput 如何打开您的文件。正如the documentation 所说:

您可以通过 openhook 参数向 fileinput.input() 或 FileInput() 提供一个打开挂钩来控制文件的打开方式。钩子必须是一个函数,它接受两个参数,文件名和模式,并返回一个相应打开的类似文件的对象。这个模块已经提供了两个有用的钩子。

所以你会这样做:

def open_utf16(name, m):
    return open(name, m, encoding="utf-16")

for line in fileinput.FileInput("file fixed.txt", openhook=open_utf16):
    ...

我使用"utf-16" 作为编码,因为这是您文件的编码,而不是"latin-1"。 8 位编码没有错误检查,因此 Latin1 将读取字节而不会注意到有任何问题,但您可能会遇到问题。如果这给您带来错误,则您的文件不在 utf-16 中。

【讨论】:

  • Alexis,你的解决方案对我有用,除了你不能就地使用和打开挂钩。我需要文件输入来写入或保存到另一个文件。再次感谢。
  • 嗯,如果是我,我会写另一个文件。但是你真的需要使用fileinput吗?你在努力推动它。如果您自己进行文件管理,生活会轻松很多。
  • @james 如果这对您有用,我会重新检查您的文件中的确切内容。打开混合编码为 utf-16 的文件可能会导致非常意外的结果。但如果你能这样读正确的话,说不定全是utf-16。
  • @viraptor,我假设文件中的所有数据都是 ascii 或 UTF-16。如果文件中确实有混合编码,最好以二进制模式读取它们(这基本上是 OP 的“latin1”方法所做的。)我的猜测是它是单一编码,但不是 utf8/16(因为“它没有用”)。
  • 我很确定这是一个混合;当我为 utf-8 或 utf-16 设置文件时,它会给我解码错误。当我使用“latin-1”编码时没有错误,我的数据保持不变。
【解决方案2】:

如果您的文件具有混合编码,您需要将其读取为二进制文件,然后根据需要解码不同的部分,或者将整个文件处理为二进制文件。问题中的latin-1 解决方案确实是偶然的。

在您的示例中,类似于:

with open('the/path', 'rb') as fi:
    data = fi.read().replace(b'old data', b'new data')
with open('other/path', 'wb') as fo:
    fo.write(data)

这是最接近您要求的内容 - 据我了解,您甚至不关心编码可能不同的字段 - 您只想更改一些内容并按原样复制文件的其余部分。二进制模式允许您这样做。

【讨论】:

    猜你喜欢
    • 2020-01-28
    • 2023-03-24
    • 2019-02-02
    • 1970-01-01
    • 1970-01-01
    • 2015-02-26
    • 2012-10-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多