【问题标题】:Python parse CSV ignoring comma with double-quotesPython解析CSV忽略带双引号的逗号
【发布时间】: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 包,但没有运气。解析会爆炸所有逗号。

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

【问题讨论】:

    标签: python python-2.7 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 设置添加到原始代码中。我的数据不需要它,所以没有使用它。我已经使用这段代码一段时间了,我很满意。
    猜你喜欢
    • 1970-01-01
    • 2017-08-08
    • 1970-01-01
    • 2015-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-15
    相关资源
    最近更新 更多