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忽略带双引号的逗号的主要内容,如果未能解决你的问题,请参考以下文章
如何在 csv 文件中忽略带引号的换行符以创建 Hive 外部表?
python 我发现Crystal Reports创建的CSV文件具有双引号字段,其中一些字段在引号之间包含逗号。我们不想