Python - 通过逗号拆分跳过括号内的内容

3

我需要按逗号分割一个字符串,但是在这种情况下我遇到了问题:

TEXT EXAMPLE (THIS IS (A EXAMPLE, BUT NOT WORKS, FOR ME)), SECOND , THIRD

我想要分割并获取以下内容:
var[0] = "TEXT EXAMPLE (THIS IS (A EXAMPLE, BUT NOT WORKS, FOR ME))"
var[1] = "SECOND"
var[2] = "THIRD"

谢谢你


2
所以问题在于并非所有逗号都应该被分割?你如何区分哪些逗号应该被分割,哪些不应该?是括号吗?这个字符串来自哪里,为什么它不使用引用来区分?如果您想要使用re.split,您的具体示例可以使用类似于,(?!.*\))的内容(即后面没有闭合括号的逗号),但这可能在一般情况下无法正常工作。 - jonrsharpe
1
对于匹配嵌套的括号(或标签或其他内容)的一般情况,您需要编写一个真正的解析器:将输入进行分词,然后根据您的语法进行解析。 - dsh
2
@Onilol,你真的读了这个问题吗?而且是“你”,请注意。 - jonrsharpe
@David,除非你能明确描述哪些逗号应该被分割,哪些不应该被分割,否则你无法告诉计算机如何做。如果你尝试过一些行不通的方法,请展示出来,这样其他人就不必再尝试同样的方法了。 - jonrsharpe
@Onilol 什么?示例输出明确显示它并没有在所有逗号上分割,所以 var.split(',') 不可能起作用,如果你不知道哪些逗号是相关的,那么把它们重新组合起来也会有同样的问题。 - jonrsharpe
显示剩余7条评论
4个回答

4
这是一个非常简单的解析器方法,适用于您的示例:
def top_level_split(s):
    """
    Split `s` by top-level commas only. Commas within parentheses are ignored.
    """

    # Parse the string tracking whether the current character is within
    # parentheses.
    balance = 0
    parts = []
    part = ''

    for c in s:
        part += c
        if c == '(':
            balance += 1
        elif c == ')':
            balance -= 1
        elif c == ',' and balance == 0:
            parts.append(part[:-1].strip())
            part = ''

    # Capture last part
    if len(part):
        parts.append(part.strip())

    return parts

my_list = top_level_split("TEXT EXAMPLE (THIS IS (A EXAMPLE, BUT NOT WORKS, FOR ME)), SECOND , THIRD")
print(my_list)

4
你可以使用基于负向前瞻的正则表达式来实现这个功能:
,(?!(?:[^(]*\([^)]*\))*[^()]*\))

这个正则表达式是用来查找逗号的,它有一个断言,确保逗号不在括号里。这是通过使用负向先行断言来实现的,它首先匹配所有匹配的(),然后匹配) 这假设括号是平衡和未转义的。

RegEx演示

代码:

>>> s = 'TEXT EXAMPLE (THIS IS (A EXAMPLE, BUT NOT WORKS, FOR ME)), SECOND , THIRD'
print re.split(r',(?!(?:[^(]*\([^)]*\))*[^()]*\))', s)

['TEXT EXAMPLE (THIS IS (A EXAMPLE, BUT NOT WORKS, FOR ME))', ' SECOND ', ' THIRD']

或者:

>>> s = 'TEXT EXAMPLE (THIS, IS (A EXAMPLE, BUT NOT WORKS, FOR ME)), SECOND , THIRD'
>>> print re.split(r',(?!(?:[^(]*\([^)]*\))*[^()]*\))', s)
['TEXT EXAMPLE (THIS, IS (A EXAMPLE, BUT NOT WORKS, FOR ME))', ' SECOND ', ' THIRD']

1
天哪,这个正则表达式太丑陋了!你能不能解释一下? - jonrsharpe
我知道这看起来很丑,因为有很多 ()。不过我在答案中尝试解释了它。 - anubhava
1
这应该被选为答案。这个正则表达式也适用于一般情况,可以忽略括号内的逗号。 - ahmet aydin
请注意,当第一个元素之前有其他项时,此方法将无法正常工作。例如,“FIRST,TEXT EXAMPLE(THIS,IS(A EXAMPLE,BUT NOT WORKS,FOR ME)),SECOND,THIRD”。在这种情况下,第一个元素将是“FIRST,TEXT EXAMPLE(...)”,而不会被拆分。 - Micha

1
感谢 jonrsharpe
text = "TEXT EXAMPLE (THIS IS (A EXAMPLE, BUT NOT WORKS, FOR ME)), SECOND , THIRD"
array = re.split(r',(?!.*\))', text)
for item in array:
    # Print and remove the first space
    print item.strip(" ")

结果:

TEXT EXAMPLE (THIS IS (A EXAMPLE, BUT NOT WORKS, FOR ME))
SECOND
THIRD

-2

你可以直接使用rsplit

l1 = "TEXT EXAMPLE (THIS IS (A EXAMPLE, BUT NOT WORKS, FOR ME)), SECOND , THIRD".rsplit(",", 2)

for line in l1:
   print line

TEXT EXAMPLE (THIS IS (A EXAMPLE, BUT NOT WORKS, FOR ME))
SECOND
THIRD

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接