Python 3.5.1混合线代码文件UTF-8和UTF-16



我已经成功地解析了我用简单的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
...

我已经能够在脚本中实现命令中的"拉丁-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()

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

您可以通过通过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中。

如果您的文件编码混合在一起,则需要将其读取为二进制,然后根据需要对不同的部分进行解码,或者只是将整个内容处理为二进制。问题中的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)

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

最新更新