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

时间:2016-06-20 17:34:50

标签: python unicode encoding 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
...

我已经能够实现" 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()

2 个答案:

答案 0 :(得分: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。

答案 1 :(得分:0)

如果您的文件具有混合编码,则需要将其作为二进制读取,然后根据需要解码不同的部分,或者仅将整个事件处理为二进制。问题中的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)

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