Python解析CSV忽略带双引号的逗号

Posted

技术标签:

【中文标题】Python解析CSV忽略带双引号的逗号【英文标题】:Python parse CSV ignoring comma with double-quotes 【发布时间】:2014-02-26 22:06:39 【问题描述】:

我有一个 CSV 文件,其中包含如下行:

"AAA", "BBB", "Test, Test", "CCC"
"111", "222, 333", "XXX", "YYY, ZZZ" 

等等……

我不想在双引号下解析逗号。 IE。我的预期结果应该是

AAA
BBB
Test, Test
CCC

我的代码:

import csv
with open('values.csv', 'rb') as f:
    reader = csv.reader(f)
    for row in reader:
        print row

我尝试在 python 下使用 csv 包,但没有运气。解析会爆炸所有逗号。

如果我遗漏了什么,请告诉我

【问题讨论】:

【参考方案1】:

应该这样做:

lines = '''"AAA", "BBB", "Test, Test", "CCC"
           "111", "222, 333", "XXX", "YYY, ZZZ"'''.splitlines()
for l in  csv.reader(lines, quotechar='"', delimiter=',',
                     quoting=csv.QUOTE_ALL, skipinitialspace=True):
    print l
>>> ['AAA', 'BBB', 'Test, Test', 'CCC']
>>> ['111', '222, 333', 'XXX', 'YYY, ZZZ']

【讨论】:

另外,如果您的 CSV 中有类似 "Test, \"Test\"" 的值,您可能还需要添加 escapechar='\\ ' 我只是需要它! :) @clarete 你救了我的命!谢谢! 这会生成一个长度为 1 的列表,这对于需要对这些值做更多事情的人来说毫无用处【参考方案2】:

输入中的引号字符前有空格。设置 skipinitialspace to True 以跳过分隔符后面的任何空格:

True 时,紧跟在分隔符 后面的空格将被忽略。默认为False

>>> import csv
>>> lines = '''\
... "AAA", "BBB", "Test, Test", "CCC"
... "111", "222, 333", "XXX", "YYY, ZZZ" 
... '''
>>> reader = csv.reader(lines.splitlines())
>>> next(reader)
['AAA', ' "BBB"', ' "Test', ' Test"', ' "CCC"']
>>> reader = csv.reader(lines.splitlines(), skipinitialspace=True)
>>> next(reader)
['AAA', 'BBB', 'Test, Test', 'CCC']

【讨论】:

这对我有帮助,但我不明白:它为什么(如何)起作用? 我不知道除了文档还能告诉你什么。逗号后面有空格,除非您将 skipinitialspace 选项设置为 true,否则这些空格将被视为列值的一部分。值周围的引号不能有引号之外的字符(或者它们不会在值周围;当逗号后的空格被视为值的一部分时,引号也是值的一部分。通过跳过空格引号是值的最外层部分,因此可以正确处理。 如果这些初始空格是 BOM \ufeff,我该怎么办? en.wikipedia.org/wiki/Byte_order_mark @tommy.carstensen:然后使用正确的编解码器打开文件。如果是 UTF-8,则使用 encoding='utf-8-sig' 自动跳过 BOM。【参考方案3】:

[张贴编辑更清楚。] 如果您不想在双引号下解析逗号,那么您的输出将包括列内的逗号,这是另一种执行此操作的方法。它很优雅,允许您使用云存储桶来存储您的 CSV 文件。关键是使用smart_open 作为标准文件打开的替代品。

另外,我使用的是DictReader 而不是阅读器。

import csv
import json
from smart_open import open

with open('./temp.csv') as csvFileObj:
    reader = csv.DictReader(csvFileObj, delimiter=',', quotechar='"')
    # csv.reader requires bytestring input in python2, unicode input in python3
    for record in reader:
        # record is a dictionary of the csv record
        print(f'Record as json shows proper reading of file:\n json.dumps(record, indent=4))')
        print(f'You can reference an individual field too: record["field3"]')
        print(f'                                           record["field4"]')

请注意,我向 DictReader 添加了 2 个参数。 分隔符=',',quotechar='"' 逗号是默认分隔符,但我添加了它以防有人需要更改它。 Quotechar 是必需的,因为它不是默认值。 代码的实际输出:

Record as json shows proper reading of file:
 
    "field1": "AAA",
    "field2": "BBB",
    "field3": "Test, Test",
    "field4": "CCC"
)
You can reference an individual field too: Test, Test
                                           CCC
done
Record as json shows proper reading of file:
 
    "field1": "111",
    "field2": "222, 333",
    "field3": "XXX",
    "field4": "YYY, ZZZ"
)
You can reference an individual field too: XXX
                                           YYY, ZZZInput file:

输入数据文件(为了清楚起见,我添加了一个标题记录。如果您没有标题记录,第一个记录将被吞噬,但也有可能的参数。)

"field1","field2","field3","field4"
"AAA","BBB","Test, Test","CCC"
"111","222, 333","XXX","YYY, ZZZ"

【讨论】:

对@TrentonMcKinney 的困惑感到抱歉。我稍微清理了代码,以便更容易遵循我正在做的事情并使用原始数据提供输出。我确实必须将 quotechar 设置添加到原始代码中。我的数据不需要它,所以没有使用它。我已经使用这段代码一段时间了,我很满意。

以上是关于Python解析CSV忽略带双引号的逗号的主要内容,如果未能解决你的问题,请参考以下文章

GROOVY - 解析CSV:忽略双引号内的逗号

如何在 csv 文件中忽略带引号的换行符以创建 Hive 外部表?

python 我发现Crystal Reports创建的CSV文件具有双引号字段,其中一些字段在引号之间包含逗号。我们不想

hive导入csv文件,字段中双引号内有逗号

从 .CSV 文件的数值中删除双引号和逗号

正则表达式在csv中找到缺少的双引号