python - 为 csv.reader 预处理一行

标签 python csv

<分区>

我正在尝试使用 csv.reader 解析一个 csv 文件。但是,此文件中的字段之一未正确编码。它是一个用双引号括起来的字符串,但字符串中的双引号没有被转义。

id,name,score
1,"something" like this",20

因为只有一个这样的字段,我应该能够通过查找第一个和最后一个双引号并转义它们之间的任何双引号来更正这个字段。有什么方法可以在 csv.reader 处理一行之前对其进行预处理以实现类似的目的吗?

最佳答案

csv.reader将愉快地从任何可迭代对象中读取行,包括生成器,因此我们可以使用生成器来进行引号转义。但我们还需要将我们的 escapechar 告诉 csv.reader .

我已将一些测试数据作为字符串列表嵌入到此代码中,但您可以将打开的文件传递给 fixlines 生成器。

import csv 

data = '''\
id,name,score
1,"something" like this",20
2,"another thing" like that",30
'''.splitlines()

def fixlines(lines):
    for row in lines:
        try:
            first = row.index('"') + 1
            last = row.rindex('"')
        except ValueError:
            pass
        else:
            stuff = row[first:last].replace('"', '\\"')
            row = row[:first] + stuff + row[last:]
        yield row

reader = csv.reader(fixlines(data), escapechar='\\')
for row in reader:
    print(row)

输出

['id', 'name', 'score']
['1', 'something" like this', '20']
['2', 'another thing" like that', '30']

此代码不会更改不包含双引号(如标题行)或一对双引号的行,但如果找到包含单个双引号的行,它可能不会完全按照您的要求执行 -引用。解决这个问题留给读者作为练习。 ;)

但是,它确实可以正确处理引号字符串中的逗号。


这也适用于 csv.DictReader :

reader = csv.DictReader(fixlines(data), escapechar='\\')
for row in reader:
    print(row)

输出

OrderedDict([('id', '1'), ('name', 'something" like this'), ('score', '20')])
OrderedDict([('id', '2'), ('name', 'another thing" like that'), ('score', '30')])

关于python - 为 csv.reader 预处理一行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50415139/

相关文章:

python - 从树莓派上的 ADC 芯片读取原始音频值

python - 如果测试失败则显示实际值

c++ - 从 std::function 创建一个 boost::python::object

python - 在 Tensorflow 1.2.0 中读取 CSV 文件

javascript - 使用 AngularJS 删除 JSON 键和值中的前导空格

python - 分配张量时Python中的ResourceExhaustedError

python - 如何从 C 代码访问 python bool 变量?

javascript - 通过从字段中删除引号、支持标题和允许其他分隔符来改进 csv 文件阅读器

java - 线程 “main”中的异常java.lang.NegativeArraySizeException

javascript - 无法通过nodejs中的fs.readFile()读取整个文件