匹配花括号之间的内容比也可以包含花括号

Match content between curly braces than also can contain curly braces

如果我有一个字符串:

s = aaa{bbb}ccc{ddd{eee}fff}ggg

是否可以根据外花括号找到所有匹配项?

m = re.findall(r'\{.+?\}', s, re.DOTALL)

returns

['{bbb}', '{ddd{eee}']

但我需要:

 ['{bbb}', '{ddd{eee}fff}']

是否可以使用 python 正则表达式?

{(?:[^{}]*{[^{]*})*[^{}]*}

尝试 this.See 演示。

https://regex101.com/r/fA6wE2/28

P.S 它只会在 {} 不超过 1 层深时起作用。

您也可以使用这个正则表达式。

\{(?:{[^{}]*}|[^{}])*}

DEMO

>>> s = 'aaa{bbb}ccc{ddd{eee}fff}ggg'
>>> re.findall(r'\{(?:{[^{}]*}|[^{}])*}', s)
['{bbb}', '{ddd{eee}fff}']

对 1 层深度使用递归正则表达式。

\{(?:(?R)|[^{}])*}

代码:

>>> import regex
>>> regex.findall(r'\{(?:(?R)|[^{}])*}', s)
['{bbb}', '{ddd{eee}fff}']

但这将得到外部 regex 模块的支持。

如果你想让它在任何深度工作,但不一定需要使用正则表达式,你可以实现一个简单的基于堆栈的自动机:

s = "aaa{bbb}ccc{ddd{eee}fff}ggg"

def getStuffInBraces(text):
    stuff=""
    count=0
    for char in text:
        if char=="{":
            count += 1
        if count > 0:
            stuff += char
        if char=="}":
            count -= 1
        if count == 0 and stuff != "":
            yield stuff
            stuff=""

getStuffInBraces是一个迭代器,所以如果你想要一个结果列表,你可以使用print(list(getStuffInBraces(s))).