Python: 特殊字符编码

3

以下是我使用的代码,用于替换文本文件中的特殊字符并将它们连接成一个单独的文件。

# -*- coding: utf-8 -*-

    import os
    import codecs

    dirpath = "C:\\Users\\user\\path\\to\\textfiles"
    filenames = os.listdir(dirpath)

    with codecs.open(r'C:\Users\user\path\to\output.txt', 'w', encoding='utf8') as outfile:
        for fname in filenames:
            currentfile = dirpath+"\\"+fname
            with codecs.open(currentfile, encoding='utf8') as infile:
        #print currentfile
                outfile.write(fname)
                outfile.write('\n')
                outfile.write('\n')

                for line in infile:

                    line = line.replace(u"´ı", "i")
                    line = line.replace(u"ï¬", "fi")
                    line = line.replace(u"fl", "fl")
                    outfile.write (line)

line.replace的第一个使用是正确的,而其他的则不行(这是有道理的),由于没有生成错误,所以我认为可能存在“可见性”问题(如果这是术语的话)。所以我做了这个:

import codecs

currentfile = 'textfile.txt'
with codecs.open('C:\\Users\\user\\path\\to\\output2.txt', 'w', encoding='utf-8') as outfile:
with open(currentfile) as infile:
for line in infile:
if "ï¬" not in line: print "not found!"

这段代码总是返回“not found!”,证明这些字符没有被读取。

当在第一个脚本中改为with codecs.open('C:\Users\user\path\to\output.txt', 'w', encoding='utf-8') as outfile:时,我会得到以下错误:

Traceback (most recent call last):
File C:\\path\\to\\concat.py, line 30, in <module>
outfile.write(line)
File C:\\Python27\\codecs.py, line 691, in write
return self.writer.write(data)
File C:\\Python27\\codecs.py, line 351, in write
data, consumed = self.encode(object, self.errors)
Unicode DecodeError: 'ascii' codec can't decode byte 0xe7 in position 0: ordinal
not in range (128)

由于我在Python方面经验不足,无法通过已有的不同来源解决问题:Python文档(12)和StackOverflow相关问题(12),我现在陷入了困境。有什么建议吗?欢迎所有答案!


我建议您打印所需替换的行和字符的“repr”。它们可能看起来相同,但在内部是不同的字符。 - Bakuriu
1个回答

0

如果您不使用编码,则使用codecs.open()没有意义。要么在读取和写入时都指定编码,要么完全放弃它。没有编码,codecs.open()只是open()的别名。

在这里,您真的需要指定要打开的文件的编解码器,以处理Unicode值。当超出ASCII字符范围时,您还应该使用unicode字面值;指定源文件编码或使用Unicode转义代码来处理数据:

# -*- coding: utf-8 -*- 
import os
import codecs

dirpath = u"C:\\Users\\user\\path\\to\\textfiles"
filenames = os.listdir(dirpath)

with codecs.open(r'C:\Users\user\path\to\output.txt', 'w', encoding='utf8') as outfile:
    for fname in filenames:
        currentfile = os.path.join(dirpath, fname)
        with codecs.open(currentfile, encoding='utf8') as infile:
            outfile.write(fname + '\n\n')
            for line in infile:
                line = line.replace(u"´ı", u"i")
                line = line.replace(u"ï¬", u"fi")
                line = line.replace(u"fl", u"fl")
                outfile.write (line)

这指定解释器使用UTF-8编解码器保存源文件,确保u"´ı"代码点正确解码为Unicode值,并且使用codec.open()打开文件时使用encoding确保读取的行被解码为Unicode值,并确保将您的Unicode值作为UTF-8写入输出文件。

请注意,dirpath值也是Unicode值。如果您使用Unicode路径,则os.listdir()返回Unicode文件名,如果这些文件名中有任何非ASCII字符,则这是必不可少的。

如果您没有做到这一点,那么很可能您的源代码编码与从文件中读取的数据不匹配,并且您正在尝试用一些ASCII字符替换错误的编码字节集。


我之前不知道u unicode转义码,所以我在我的脚本中添加了它。不幸的是,没有任何变化,我仍然得到相同的错误。 - user1834437
追溯(Traceback)最近的一次调用: 文件C:\path\to\concat.py,第15行,在<module>中 outfile.write(fname + '\n\n') 文件C:\Python27\codecs.py,第691行,写入(write) 返回self.writer.write(data) 文件C:\Python27\codecs.py,第351行,写入(write) data,consumed = self.encode(object, self.errors) Unicode DecodeError:'ascii'编解码器无法解码位置0的字节0xe7:序数不在范围内(128) - user1834437
@LDN-5602:这意味着您正在尝试编写字节字符串(而不是 Unicode 值),为了将它们编码为 UTF-8,需要先将它们解码为 Unicode。使用默认编解码器 ASCII 对其进行编码会失败。您确定您也在打开要读取的文件时使用了编码吗?换句话说,您是否应用了我建议的所有更改? - Martijn Pieters
这不是编解码器的问题。使用print repr(line)来显示您拥有哪种类型的数据。如果开头没有u,则表示您没有Unicode。 - Martijn Pieters
那里没有引号吗?是 u'Agroqu\xc2\xc4\xb1mica' 还是 'Agroqu\xc2\xc4\xb1mica' - Martijn Pieters
显示剩余20条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接