在python中使用嵌套子括号删除双曲线括号之间的数据

the*_*ror 13 python regex parsing

我对这个问题有些困难.我需要删除包含在波浪括号中的所有数据.

像这样:

Hello {{world of the {{ crazy}} {{need {{ be}}}} sea }} there.
Run Code Online (Sandbox Code Playgroud)

变为:

Hello there.
Run Code Online (Sandbox Code Playgroud)

这是我的第一次尝试(我知道这很糟糕):

while 1:
    firstStartBracket = text.find('{{')
    if (firstStartBracket == -1):
        break;
    firstEndBracket = text.find('}}')
    if (firstEndBracket == -1):
        break;
    secondStartBracket = text.find('{{',firstStartBracket+2);
    lastEndBracket = firstEndBracket;
    if (secondStartBracket == -1 or secondStartBracket > firstEndBracket):
        text = text[:firstStartBracket] + text[lastEndBracket+2:];
        continue;
    innerBrackets = 2;
    position = secondStartBracket;
    while innerBrackets:
        print innerBrackets;
        #everytime we find a next start bracket before the ending add 1 to inner brackets else remove 1
        nextEndBracket = text.find('}}',position+2);
        nextStartBracket = text.find('{{',position+2);
        if (nextStartBracket != -1 and nextStartBracket < nextEndBracket):
            innerBrackets += 1;
            position = nextStartBracket;
            # print text[position-2:position+4];
        else:
            innerBrackets -= 1;
            position = nextEndBracket;
            # print text[position-2:position+4];
            # print nextStartBracket
            # print lastEndBracket
            lastEndBracket = nextEndBracket;
        print 'pos',position;
    text = text[:firstStartBracket] + text[lastEndBracket+2:];
Run Code Online (Sandbox Code Playgroud)

它似乎工作但很快耗尽内存.有没有更好的方法来做到这一点(希望与正则表达式)?

编辑:我不清楚所以我会举一个例子.我需要允许多个顶级括号.

像这样:

Hello {{world of the {{ crazy}} {{need {{ be}}}} sea }} there {{my }} friend.
Run Code Online (Sandbox Code Playgroud)

变为:

Hello there friend.
Run Code Online (Sandbox Code Playgroud)

Jas*_*n S 4

这是一个基于正则表达式/生成器的解决方案,适用于任意数量的大括号。这个问题不需要实际的堆栈,因为只涉及一种类型(好吧,对)的令牌。它所level扮演的角色就像堆栈在更复杂的解析器中所扮演的角色一样。

import re

def _parts_outside_braces(text):
    level = 0
    for part in re.split(r'(\{\{|\}\})', text):
        if part == '{{':
            level += 1
        elif part == '}}':
            level = level - 1 if level else 0
        elif level == 0:
            yield part

x = 'Hello {{world of the {{ crazy}} {{need {{ be}}}} sea }} there.  {{ second set {{ of }} braces }}'
print(''.join(_parts_outside_braces(x)))
Run Code Online (Sandbox Code Playgroud)

更一般的观点...正则表达式中的捕获组使大括号显示在 的输出中re.split,否则您只能得到中间的内容。还有一些对不匹配括号的支持。对于严格的解析器,这应该引发异常,因为应该以 level > 0 的方式从字符串末尾运行。对于松散的 Web 浏览器样式解析器,也许您希望将它们显示为}}输出...