Python 分隔符行拆分问题

9 投票
3 回答
771 浏览
提问于 2025-04-18 10:06

我在尝试根据不同的分隔符来拆分文本行,同时还想保留空字段和带引号的数据,这让我很头疼。

举个例子:

1,"2",three,'four, 4',,"6\tsix"

或者用制表符分隔的版本

1\t"2"\tthree\t'four, 4'\t\t"6\tsix"

这两种情况都应该得到:

['1', '"2"', 'three', 'four, 4', '', "6\tsix"]

到目前为止,我尝试过:

  1. 使用split函数,但显然对于带引号的分隔符处理得不太好。

  2. 用csv库的解决方案,但它通常会把所有内容都加上引号或者一个都不加,无法保留原来的引号。

  3. 使用正则表达式,特别是参考了下面这个答案的模式,但它会丢掉空字段: 如何拆分但忽略带引号字符串中的分隔符,在python中?

  4. 使用pyparsing库。我目前能做到的最好效果是这样的,但这也会丢掉空字段(用逗号作为分隔符的例子):

    s = '1,"2",three,\'four, 4\',,"6\tsix"'
    wordchars = (printables + ' \t\r\n').replace(',', '', 1)
    delimitedList(OneOrMore(quotedString | Word(wordchars)), ',').parseWithTabs().parseString(s)
    

谢谢大家的建议!

3 个回答

2

你为什么说正则表达式会丢掉空字段呢?Alan More在这篇帖子中的回答提到:

re.split(''';(?=(?:[^'"]|'[^']*'|"[^"]*")*$)''', data)

我试了一下(把;换成,),结果得到了['1', '"2"', 'three', "'four, 4'", '', '"6\tsix"'],这就是你所说的预期结果。

3

使用这个模式可以匹配双引号外的逗号
,(?=(?:(?:[^"]*\"){2})*[^"]*$)
演示

编辑:
如果想要分割双引号或单引号外的逗号,可以使用这个模式
,(?=(?:(?:[^'\"]*(?:\"|')){2})*[^'\"]*$)
演示

7

这个对我有效:

import pyparsing as pyp

pyp.delimitedList(pyp.quotedString | pyp.SkipTo(',' | pyp.LineEnd()), ',') \
    .parseWithTabs().parseString(s)

结果是

['1', '"2"', 'three', "'four, 4'", '', '"6\tsix"']

要避免创建包含空格字符或所有可打印字符的单词。Pyparsing 不会进行任何预查看,这些表达式可能会包含比你预想的更多内容。

撰写回答