【问题标题】:Python delimited line split problemsPython定界线分割问题
【发布时间】:2014-08-07 16:59:19
【问题描述】:

我正在努力根据变量分隔符拆分文本行,并保留空字段和引用的数据。

例子:

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. 使用拆分,但显然没有按需要处理带引号的分隔符。

  2. 使用 csv 库的解决方案,但它往往具有引用所有内容或不引用任何内容的选项,而不保留原始引号。

  3. 正则表达式,特别是遵循以下答案中的模式,但它会删除空字段:How to split but ignore separators in quoted strings, in 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)
    

感谢您的任何想法!

【问题讨论】:

  • 要使拆分工作,您需要使用保证不会出现在字符串中其他任何位置的字符或字符组合。也许您可以使用不在键盘上的转义字符?
  • 恐怕我无法控制输入文件,所以无法决定分隔符。不过感谢您的想法!
  • 在这种情况下,正则表达式可能是要走的路。虽然不确定确切的语法。
  • 用逗号分割然后修剪
  • 每个文本文件中是否总是有相同数量的字段(例如 6 个)?

标签: python regex csv split pyparsing


【解决方案1】:

使用此模式匹配双引号外的逗号
,(?=(?:(?:[^"]*\"){2})*[^"]*$)
Demo

编辑: 在双引号或引号之外拆分逗号使用此模式
,(?=(?:(?:[^'\"]*(?:\"|')){2})*[^'\"]*$)
Demo

【讨论】:

  • 我认为这个版本可能有效,但在匹配信息下它说:“没有提取匹配组。这意味着您的模式匹配但其中没有(捕获(组))匹配任何内容在主题字符串中。”所以我不确定。
  • 它是为了使用匹配的逗号作为你的分割模式
  • re.split(r',(?=(?:(?:[^"]*\"){2})*[^"]*$)', txt1) 返回 ['1', '"2"', 'three', "'four", " 4'", '', '"6\tsix"'], @alphabravo ,如果你证明它有效,你将获得更多的选票。
  • 所以这个版本将'四,4'分成2,而另一个版本将它们保持在一起。不确定在这种情况下哪个版本是正确的。
  • 我不知道使用双引号和单引号的 CSV 文件,但更新了我的模式以解决此问题。
【解决方案2】:

你为什么说正则表达式会丢弃空字段? Alan More 在referenced post 中的回答建议

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

我试过了(将;改成,后)发现['1', '"2"', 'three', "'four, 4'", '', '"6\tsix"']你说的期望是什么

【讨论】:

    【解决方案3】:

    这对我有用:

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

    给予

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

    避免使用空白字符或所有可打印字符创建单词。 Pyparsing 不会进行任何前瞻操作,这些表达式可能包含的内容可能比您计划的要多。

    【讨论】:

    • 什么库?我尝试使用完整路径,以便其他人可以更好地遵循。
    • 对不起,我在捎带 OP 对 pyparsing 的引用。
    • 这行得通!太感谢了!以下适用于制表符分隔的版本(相同但具有 White 类)。也许这很明显,但我是 pyparsing 的新手,如果你不知道的话。 delimitedList(quotedString | SkipTo(White('\t') | LineEnd()), White('\t')).parseWithTabs().parseString(s)。再次感谢!
    • 如果您希望从已解析的带引号的字符串中去掉引号,pyparsing 会在解析时为您执行此操作 - 在您的解析器定义之前,添加 pyp.quotedString.setParseAction(pyp.removeQuotes)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-23
    • 1970-01-01
    • 2022-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多