我需要像这样拆分字符串,使用分号。但我不想拆分字符串(‘或")中的分号,我不是在解析文件;我只是解析一个没有换行的简单字符串。
part 1;"this is ; part 2;";'this is ; part 3';part 4;this "is ; part" 5
结果应该是:
我认为这可以使用正则表达式来完成,但如果不能,我可以采用另一种方法。
发布于 2010-05-07 15:59:50
大多数答案似乎都过于复杂了。You ‘t back references。 ‘t 不需要依赖于re.findall是否提供重叠匹配。假设输入不能被csv模块解析,因此正则表达式是唯一可行的方法,您所需要的就是使用与字段匹配的模式调用re.split。
注意,在这里匹配字段要比匹配分隔符容易得多:
import re
data = """part 1;"this is ; part 2;";'this is ; part 3';part 4;this "is ; part" 5"""
PATTERN = re.compile(r'''((?:[^;"']|"[^"]*"|'[^']*')+)''')
print PATTERN.split(data)[1::2]
输出结果为:
['part 1', '"this is ; part 2;"', "'this is ; part 3'", 'part 4', 'this "is ; part" 5']
正如Jean-Luc Nacif Coelho正确指出的那样,这将无法正确处理空组。这取决于可能或不重要的情况。如果这很重要,例如,可以通过将
';;'
替换为
';<marker>;'
来处理它,其中
<marker>
必须是您知道在拆分之前不会出现在数据中的某个字符串(不带分号)。此外,您还需要在以下情况下恢复数据:
>>> marker = ";!$%^&;"
>>> [r.replace(marker[1:-1],'') for r in PATTERN.split("aaa;;aaa;'b;;b'".replace(';;', marker))[1::2]]
['aaa', '', 'aaa', "'b;;b'"]
然而,这是一个杂乱无章的东西。有什么更好的建议吗?
发布于 2010-05-07 18:57:58
re.split(''';(?=(?:[^'"]|'[^']*'|"[^"]*")*$)''', data)
每次找到分号时,lookahead都会扫描整个剩余的字符串,确保有偶数个单引号和一个偶数个双引号。(忽略双引号字段中的单引号,反之亦然。)如果先行操作成功,分号就是分隔符。
与匹配字段而不是分隔符的
Duncan's solution
不同,它不存在空字段的问题。(甚至不是最后一个:与许多其他
split
实现不同,Python的实现不会自动丢弃尾随的空字段。)
发布于 2016-02-23 12:38:14
>>> a='A,"B,C",D'
>>> a.split(',')
['A', '"B', 'C"', 'D']
It failed. Now try csv module
>>> import csv
>>> from StringIO import StringIO
>>> data = StringIO(a)