Python delimited line split problems
我正在努力根据变量分隔符拆分文本行,并保留空字段和引用数据。
示例:
1
| 1,"2",three,'four, 4',,"6\tsix" |
或以制表符分隔的维西翁
1
| 1\t"2"\tthree\t'four, 4'\t\t"6\tsix" |
号
两者都会导致:
1
| ['1', '"2"', 'three', 'four, 4', '',"6\tsix"] |
到目前为止,我试过:
使用split,但显然所引用的分隔符没有按需要处理。
解决方案使用csv库,但它往往有选项可以引用所有内容或不引用任何内容,而不保留原始引用。
regex,特别是从下面的答案中遵循模式,但它会删除空字段:如何拆分但忽略在python中带引号的字符串中的分隔符?
使用PyParsing库。我所管理的最好的方法如下,但这也会删除空字段(使用逗号分隔符示例):
1 2 3 4 5
| s = '1,"2",three,\'four, 4\',,"6\tsix"'
wordchars = (printables + ' \t
').replace(',', '', 1)
delimitedList(OneOrMore(quotedString | Word(wordchars)), ',').parseWithTabs().parseString(s) |
。
谢谢你的建议!
- 要使拆分生效,您需要使用一个保证不会出现在字符串中任何其他位置的字符或字符组合。也许你可以用一个不在键盘上的转义符?
- 恐怕我无法控制输入文件,所以无法决定分隔符。不过,谢谢你的建议!
- 在这种情况下,regex可能是一个不错的选择。但不确定确切的语法。
- 用逗号分隔,然后修剪
- 每个文本文件中的字段数是否总是相同(例如6个)?
- @似乎很接近,但它分割了"四"和"四",而这不是OP想要的。
- 等等,"4,4"应该拆分为数组的两个独立成员,还是应该是同一个成员?
- 为什么说regex会丢弃空字段?阿兰·莫尔在参考文章中的回答建议使用re.split(''';(?=(?:[^'"]|'[^']*'|"[^"]*")*$)''', data)。我试了一下(在用,换了;之后),发现['1', '"2"', 'three',"'four, 4'", '', '"6\tsix"']和你说的一样。
这对我很有用:
1 2 3 4
| import pyparsing as pyp
pyp.delimitedList(pyp.quotedString | pyp.SkipTo(',' | pyp.LineEnd()), ',') \
.parseWithTabs().parseString(s) |
给予
1
| ['1', '"2"', 'three',"'four, 4'", '', '"6\tsix"'] |
号
避免创建带有空白字符或所有可打印字符的单词。Pyparlysis不做任何前瞻性工作,而且这些表达式可能包含比您计划的更多的内容。
- 什么自由?我试着使用完整的路径,以便其他人更好地跟随。
- 不好意思,我在引用OP的pyparsing。
- 这很管用!非常感谢!以下内容适用于以制表符分隔的版本(与白色类相同)。也许这很明显,但如果你不知道的话,我对Pyparsing还是个新手。delimitedList(quotedString | SkipTo(White('\t') | LineEnd()), White('\t')).parseWithTabs().parseString(s)。再次感谢!
- 如果您希望从解析的引用字符串中去掉引号,Pyparsing将在解析时为您做到这一点—在您的解析器定义之前,添加pyp.quotedString.setParseAction(pyp.removeQuotes)。
使用此模式匹配双引号外的逗号,(?=(?:(?:[^"]*\"){2})*[^"]*$)。演示
编辑:要在双引号或引号之外拆分逗号,请使用此模式江户十一〔一〕号演示
- 我认为这个版本可能有效,但在匹配信息下,它说:"没有提取匹配组。这意味着您的模式匹配,但其中没有(捕获(组))匹配主题字符串中的任何内容。"所以我不确定。
- 它的目的是使用匹配的逗号作为分割模式
- re.split(r',(?=(?:(?:[^"]*"){2})*[^"]*$)', txt1)返回['1', '"2"', 'three',"'four"," 4'", '', '"6\tsix"'],@alphabravo,如果你证明它有效,你会得到更多的选票。
- 所以这个版本把"4,4"分成2个,而另一个版本把它们放在一起。在这种情况下,不确定哪个版本是正确的。
- 我不知道一个使用双引号和单引号的csv文件,但更新了我的模式来解决这个问题。
为什么说regex会丢弃空字段?艾伦·莫尔在参考文章中的回答建议
1
| re.split(''';(?=(?:[^'"]|'[^']*'|"[^"]*")*$)''', data) |
我试了一下(在用,换了;之后),发现['1', '"2"', 'three',"'four, 4'", '', '"6\tsix"']和你说的一样