Python 字符串替换 UTF-16-LE 文件

7 投票
2 回答
20441 浏览
提问于 2025-04-16 07:08

Python 2.6

在处理UTF-16-LE格式的文件时,使用Python的string.replace()方法似乎不起作用。我想到两种解决办法:

  1. 找一个可以处理Unicode字符串的Python模块。
  2. 把目标Unicode文件转换成ASCII格式,使用string.replace()方法,然后再转换回去。不过我担心这样可能会丢失一些数据。

大家能给我推荐一个好的解决办法吗?谢谢。

编辑:

我的代码大概是这样的:

infile = open(inputfilename)
for s in infile:
 outfile.write(s.replace(targetText, replaceText))

看起来这个for循环可以正确解析每一行。我这里有没有犯什么错误?

编辑2:

我看过Python的Unicode教程,并尝试了下面的代码,结果成功了。不过,我在想有没有更好的方法来做这件事。有人能帮忙吗?谢谢。

infile = codecs.open(infilename,'r', encoding='utf-16-le')

newlines = []
for line in infile:
    newlines.append(line.replace(originalText,replacementText))

outfile = codecs.open(outfilename, 'w', encoding='utf-16-le')
outfile.writelines(newlines)

我需要关闭输入文件和输出文件吗?

2 个回答

1

Python 3

看起来在Python 3.6中,如果你以文本模式打开文件,它默认会认为你的文件是UTF-8编码的:

>>> open('/etc/hosts')
<_io.TextIOWrapper name='/etc/hosts' mode='r' encoding='UTF-8'>

file.readlines() 这样的函数会返回字符串对象,而在Python 3中,字符串是unicode格式的。如果你以二进制模式打开文件,行为就会和Python 2差不多:

>>> open('/etc/hosts', 'rb)
<_io.BufferedReader name='/etc/hosts'>

在这种情况下,readlines 会返回 bytes 对象,你需要进行解码才能得到unicode格式:

>>> type(open('/etc/hosts', 'rb').readline())
bytes

>>> type(open('/etc/hosts', 'rb').readline().decode('utf-8'))
str

你可以通过 encoding 参数使用其他编码方式打开文件:

>>> open('/etc/hosts', encoding='ascii')
<_io.TextIOWrapper name='/etc/hosts' mode='r' encoding='ascii'>

Python 2(这是一个非常旧的回答)

Python 2对编码不太在意,文件就是一串字节流。像 file.readlines() 这样的函数会返回 str 对象,而不是 unicode,即使你以文本模式打开文件。你可以使用 str.decode('你的文件编码') 将每一行转换为unicode对象。

>>> f = open('/etc/issue')
>>> l = f.readline()
>>> l
'Ubuntu 10.04.1 LTS \\n \\l\n'
>>> type(l)
<type 'str'>
>>> u = l.decode('utf-8')
>>> type(u)
<type 'unicode'>

你可以使用 codecs.open 来获得类似Python 3的结果,而不是仅仅使用 open

12

你没有一个Unicode文件。其实根本就没有这种东西(除非你是记事本的作者,因为他们把“Unicode”和“UTF-16LE”搞混了)。

请阅读一下Python Unicode入门指南Joel关于Unicode的文章

更新 我很高兴你看了推荐的资料后有所帮助。这里有一个更好的代码版本:

infile = codecs.open(infilename,'r', encoding='utf-16-le')
outfile = codecs.open(outfilename, 'w', encoding='utf-16-le')
for line in infile:
    fixed_line = line.replace(originalText,replacementText)
    # no need to save up all the output lines in a list
    outfile.write(fixed_line)
infile.close()
outfile.close()

养成一个好习惯,完成工作后立即释放资源(比如关闭文件)。更重要的是,对于输出文件,通常在你关闭文件之前,目录是不会更新的。

了解一下“with”语句,看看如何更好地处理文件。

撰写回答