我需要一个正则表达式来选择两个外括号之间的所有文本。

例子: START_TEXT(这里的文本(可能的文本)文本(可能的文本(更多的文本))END_TXT ^ ^

结果: (此处文本(可能的文本)文本(可能的文本(更多的文本)))


当前回答

答案取决于您是需要匹配括号的匹配集,还是只需要匹配输入文本中的第一个开始到最后一个结束的括号。

如果您需要匹配匹配的嵌套括号,那么您需要的不仅仅是正则表达式。-见@dehmann

如果只是先开后关,再见@扎克

决定你想要发生什么:

abc ( 123 ( foobar ) def ) xyz ) ghij

您需要决定在这种情况下您的代码需要匹配什么。

其他回答

这个答案解释了为什么正则表达式不是这项任务的正确工具的理论局限性。


正则表达式不能做到这一点。

正则表达式基于有限状态自动机(FSA)的计算模型。顾名思义,FSA只能记住当前状态,它没有关于以前状态的信息。

在上图中,S1和S2是两种状态,其中S1是开始和结束步骤。因此,如果我们尝试使用字符串0110,转换如下:

      0     1     1     0
-> S1 -> S2 -> S2 -> S2 ->S1

在上述步骤中,当我们在第二个S2,即解析完0110的01之后,FSA没有关于01中前一个0的信息,因为它只能记住当前状态和下一个输入符号。

在上面的问题中,我们需要知道左括号的no;这意味着它必须存储在某个地方。但是由于fsa不能这样做,因此不能编写正则表达式。

但是,可以编写一个算法来完成这项任务。算法一般属于下推自动机(PDA)。PDA比FSA高一级。PDA有一个额外的堆栈来存储一些额外的信息。pda可以用来解决上述问题,因为我们可以在堆栈中“推入”开括号,并在遇到闭括号时“弹出”它们。如果在结束时,堆栈为空,则开始括号和结束括号匹配。否则不。

这个也有用

re.findall(r'\(.+\)', s)

在处理嵌套模式和正则表达式是解决这类问题的正确工具时,我也陷入了这种情况。

/(\((?>[^()]+|(?1))*\))/

我没有使用正则表达式,因为它很难处理嵌套代码。因此,这个代码片段应该能够允许你抓取带有平衡括号的代码段:

def extract_code(data):
    """ returns an array of code snippets from a string (data)"""
    start_pos = None
    end_pos = None
    count_open = 0
    count_close = 0
    code_snippets = []
    for i,v in enumerate(data):
        if v =='{':
            count_open+=1
            if not start_pos:
                start_pos= i
        if v=='}':
            count_close +=1
            if count_open == count_close and not end_pos:
                end_pos = i+1
        if start_pos and end_pos:
            code_snippets.append((start_pos,end_pos))
            start_pos = None
            end_pos = None

    return code_snippets

我使用它从文本文件中提取代码片段。

使用Ruby(1.9.3或更高版本)的正则表达式:

/(?<match>\((?:\g<match>|[^()]++)*\))/

关节演示