Python处理CSV文件以移除大于3字节的Unicode字符
我正在使用Python 2.7.5,想处理一个现有的CSV文件,目的是去掉那些超过3个字节的unicode字符。(因为我要把这个文件发送到Mechanical Turk,而这是亚马逊的限制。)
我尝试使用这个问题中最好的答案(如何过滤(或替换)超过3个字节的unicode字符?)。我想我可以逐行遍历CSV文件,遇到超过3个字节的unicode字符时,就用一个替代字符来替换它们。
# -*- coding: utf-8 -*-
import csv
import re
re_pattern = re.compile(u'[^\u0000-\uD7FF\uE000-\uFFFF]', re.UNICODE)
ifile = open('sourcefile.csv', 'rU')
reader = csv.reader(ifile, dialect=csv.excel_tab)
ofile = open('outputfile.csv', 'wb')
writer = csv.writer(ofile, delimiter=',', quotechar='"', quoting=csv.QUOTE_ALL)
#skip header row
next(reader, None)
for row in reader:
writer.writerow([re_pattern.sub(u'\uFFFD', unicode(c).encode('utf8')) for c in row])
ifile.close()
ofile.close()
但是我现在遇到了这个错误:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xea in position 264: ordinal not in range(128)
所以虽然我能正确遍历一些行,但一到那些奇怪的unicode字符就停下来了。
我真的很感激一些指点;我完全搞不清楚。我把'utf8'换成了'latin1',还把unicode(c).encode改成了unicode(c).decode,但还是一直出现同样的错误。
1 个回答
3
你的输入数据仍然是编码过的数据,而不是Unicode值。你需要先解码成unicode
值,但你没有指定要使用哪种编码。然后,你还需要再编码回编码值,以便写回输出的CSV文件:
writer.writerow([re_pattern.sub(u'\uFFFD', unicode(c, 'utf8')).encode('utf8')
for c in row])
你的错误来自于unicode(c)
这个调用;如果没有明确指定使用的编码,Python会默认使用ASCII编码。
如果你把文件对象当作上下文管理器使用,就不需要手动关闭它们:
import csv
import re
re_pattern = re.compile(u'[^\u0000-\uD7FF\uE000-\uFFFF]', re.UNICODE)
def limit_to_BMP(value, patt=re_pattern):
return patt.sub(u'\uFFFD', unicode(value, 'utf8')).encode('utf8')
with open('sourcefile.csv', 'rU') as ifile, open('outputfile.csv', 'wb') as ofile:
reader = csv.reader(ifile, dialect=csv.excel_tab)
writer = csv.writer(ofile, delimiter=',', quotechar='"', quoting=csv.QUOTE_ALL)
next(reader, None) # header is not added to output file
writer.writerows(map(limit_to_BMP, row) for row in reader)
我把替换的操作移到了一个单独的函数里,并使用生成器表达式按需生成所有行,以便给writer.writerows()
函数使用。