Python处理csv文件以删除大于3个字节的unicode字符

时间:2014-08-18 11:27:51

标签: python csv unicode

我正在使用Python 2.7.5并尝试获取现有的CSV文件并对其进行处理以删除大于3个字节的unicode字符。 (发送给机械土耳其人,这是亚马逊的限制。)

我试图在这个问题(How to filter (or replace) unicode characters that would take more than 3 bytes in UTF-8?)中使用顶级(惊人)答案。我假设我可以逐行遍历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字符时会停止。

我真的很感激一些指示;我完全糊涂了。我已经取代了#ut; utf8'与' latin1'和unicode(c)。编码到unicode(c).decode并且我一直得到同样的错误。

1 个答案:

答案 0 :(得分: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()函数的所有行。