【问题标题】:Python - Split a row into columns - csv dataPython - 将一行拆分为列 - csv数据
【发布时间】:2016-12-15 18:56:53
【问题描述】:

我正在尝试从 csv 文件中读取数据,将每一行拆分为相应的列。

但是当特定列本身带有逗号时,我的正则表达式会失败。

例如:a,b,c,"d,e,g,",f

我想要这样的结果:

a    b    c    "d,e, g,"    f  

这是 5 列。

这里是用逗号分割字符串的正则表达式

,(?=(?:"[^"]?(?:[^"])*))|,(?=[^"]+(?:,)| ,+|$)

但它对少数字符串失败,而对其他字符串有效。

我正在寻找的是,当我使用 pyspark 从 csv 读取数据到 dataframe/rdd 时,我想加载/保留所有列而不会出现任何错误

谢谢

【问题讨论】:

标签: python regex csv pyspark rdd


【解决方案1】:

在更新的regex 模块的帮助下容易得多:

import regex as re

string = 'a,b,c,"d,e, g,",f'
rx = re.compile(r'"[^"]*"(*SKIP)(*FAIL)|,')

parts = rx.split(string)
print(parts)
# ['a', 'b', 'c', '"d,e, g,"', 'f']

它支持(*SKIP)(*FAIL) 机制,在此示例中忽略双引号之间的所有内容。


如果你已经转义了双引号,你可以使用:
import regex as re

string = '''a,b,c,"d,e, g,",f, this, one, with "escaped \"double",quotes:""'''
rx = re.compile(r'".*?(?<!\\)"(*SKIP)(*FAIL)|,')
parts = rx.split(string)
print(parts)
# ['a', 'b', 'c', '"d,e, g,"', 'f', ' this', ' one', ' with "escaped "double",quotes:""']

regex101.com 上查看后者的演示。


对于近 50 分,我觉得也提供 csv 方法:
import csv
string = '''a,b,c,"d,e, g,",f, this, one, with "escaped \"double",quotes:""'''

# just make up an iterable, normally a file would go here
for row in csv.reader([string]):
    print(row)
    # ['a', 'b', 'c', 'd,e, g,', 'f', ' this', ' one', ' with "escaped "double"', 'quotes:""']

【讨论】:

    【解决方案2】:

    试试\,(?=([^"\\]*(\\.|"([^"\\]*\\.)*[^"\\]*"))*[^"]*$)

    使用this answer which explains how to match everything that is not in quotes ignoring escaped quoteshttp://regexr.com/ 进行测试。

    请注意 - 作为您问题状态的其他答案 - 解析 CSV 的方法比使用正则表达式更好。

    【讨论】:

      【解决方案3】:

      您无法使用正则表达式轻松解析 CSV 文件。

      我从 Unix 命令行处理 CSV 的首选工具包是 csvkit,您可以从 https://csvkit.readthedocs.io 获得。它还有一个 Python 库。

      标准 csv 库的 Python 文档在这里:https://docs.python.org/2/library/csv.html

      这里有关于解析 CSV 的广泛讨论:

      https://softwareengineering.stackexchange.com/questions/166454/can-the-csv-format-be-defined-by-a-regex

      这是一条老路,而且库已经足够好,您不应该编写自己的代码。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-10-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多