【发布时间】:2014-01-03 03:41:36
【问题描述】:
这个问题已经被问过很多次了。一些例子:[1]、[2]。但似乎没有更普遍的东西。我正在寻找的是一种以逗号分隔不在引号或分隔符对内的字符串的方法。例如:
s1 = 'obj<1, 2, 3>, x(4, 5), "msg, with comma"'
应该分成三个元素的列表
['obj<1, 2, 3>', 'x(4, 5)', '"msg, with comma"']
现在的问题是这会变得更加复杂,因为我们可以查看成对的 <> 和 ()。
s2 = 'obj<1, sub<6, 7>, 3>, x(4, y(8, 9), 5), "msg, with comma"'
应该拆分成:
['obj<1, sub<6, 7>, 3>', 'x(4, y(8, 9), 5)', '"msg, with comma"']
不使用正则表达式的天真解决方案是通过查找字符,<( 来解析字符串。如果找到< 或(,则我们开始计算奇偶校验。如果奇偶校验为零,我们只能以逗号分隔。比如说我们要拆分s2,我们可以从parity = 0开始,当我们到达s2[3]时,我们遇到<,这将使奇偶校验增加1。奇偶校验只有在遇到>或@时才会减少987654341@,遇到<或(会增加。虽然奇偶校验不为 0,但我们可以简单地忽略逗号而不进行任何拆分。
这里的问题是,有没有办法用正则表达式快速做到这一点?我真的在研究这个solution,但这似乎并不涵盖我给出的例子。
更通用的函数是这样的:
def split_at(text, delimiter, exceptions):
"""Split text at the specified delimiter if the delimiter is not
within the exceptions"""
有些用途是这样的:
split_at('obj<1, 2, 3>, x(4, 5), "msg, with comma"', ',', [('<', '>'), ('(', ')'), ('"', '"')]
正则表达式是否能够处理这个问题,或者是否有必要创建一个专门的解析器?
【问题讨论】:
-
在这种情况下,正则表达式对您没有帮助,因为您尝试解析的语言(即字符串组)不规则。鉴于您允许标签的任意嵌套,没有简单的方法可以通过正则表达式摆脱这种情况。
-
Regex 实际上不能处理这个问题,你也不想这样。复杂性至少是线性的,因此您必须始终使用奇偶校验检查器获得更好的性能。不过,您不必自己构建它。 Python 的
csv模块做了很多工作。 -
啊,不要说正则表达式不能处理它!也许 python 风味不能,但其他风味如 PCRE 可以做到!这是a proof,我们甚至可能会花哨并使用递归模式来考虑嵌套的
<>() -
如果您知道括号内元素的最大嵌套递归深度,也可以使用正则表达式。但是在没有 recursive regex support 的 Python 中,使用更易于维护的解析器函数。
-
Aaaand I did it,现在的问题是我为什么要 O_o ?