如何删除字符串中外括号之间的所有文本?

How to remove all text between the outer parentheses in a string?

当我有这样的字符串时:

s1 = 'stuff(remove_me)'

我可以轻松删除使用中的括号和文本

# returns 'stuff'
res1 = re.sub(r'\([^)]*\)', '', s1)

解释为 here

但我有时会遇到这样的嵌套表达式:

s2 = 'stuff(remove(me))'

当我运行上面的命令时,我得到

'stuff)'

我也试过:

re.sub('\(.*?\)', '', s2)

这给了我相同的输出。

如何删除外括号内的所有内容 - 包括括号本身 - 以便我也以 'stuff' 结束(这应该适用于任意复杂的表达式)?

re 匹配很急切,因此他们会尝试匹配尽可能多的文本,对于您提到的简单测试用例,只需让正则表达式 运行:

>>> re.sub(r'\(.*\)', '', 'stuff(remove(me))')
'stuff'

如果你确定括号最初是平衡的,就用greedy版本:

re.sub(r'\(.*\)', '', s2)

https://regex101.com/r/kQ2jS3/1

'(\(.*\))'

这会捕获 furthest 括号以及括号之间的所有内容。

您的旧正则表达式捕获第一个括号,以及 next 括号之间的所有内容。

如前所述,您需要 recursive regex 来匹配任意级别的嵌套,但如果您知道最多只能有一个嵌套级别,请尝试使用此模式:

\((?:[^)(]|\([^)(]*\))*\)
  • [^)(] 匹配一个字符,不是括号 (negated class)。
  • |\([^)(]*\) 或它匹配另一个 ( ) 对与任意数量的 non )( inside.
  • (?:...)* 所有这一切在 ( )
  • 中任意次数

Here is a demo at regex101

在交替之前使用 [^)(] 没有 + 量词,如果不平衡则失败更快。
您需要添加更多可能发生的嵌套级别。例如,最多 2 个级别:

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

Another demo at regex101

注意\(.*\) 匹配左起第一个 (,然后匹配任何 0+ 个字符(如果 DOTALL 修饰符是换行符除外)未启用)直到 last),并且不考虑正确嵌套的括号。

要使用 Python 中的正则表达式正确删除嵌套括号,您可以使用简单的 \([^()]*\) (matching a (, then 0+ chars other than ( and ) and then a )) in a while block using re.subn:

def remove_text_between_parens(text):
    n = 1  # run at least once
    while n:
        text, n = re.subn(r'\([^()]*\)', '', text)  # remove non-nested/flat balanced parts
    return text

基本上:删除里面没有 ()(...),直到找不到匹配项。用法:

print(remove_text_between_parens('stuff (inside (nested) brackets) (and (some(are)) here) here'))
# => stuff   here

也可以使用非正则表达式的方式:

def removeNestedParentheses(s):
    ret = ''
    skip = 0
    for i in s:
        if i == '(':
            skip += 1
        elif i == ')'and skip > 0:
            skip -= 1
        elif skip == 0:
            ret += i
    return ret

x = removeNestedParentheses('stuff (inside (nested) brackets) (and (some(are)) here) here')
print(x)              
# => 'stuff   here'

another Python demo

我在这里找到了解决方案:

http://rachbelaid.com/recursive-regular-experession/

上面写着:

>>> import regex
>>> regex.search(r"^(\((?1)*\))(?1)*$", "()()") is not None
True
>>> regex.search(r"^(\((?1)*\))(?1)*$", "(((()))())") is not None
True
>>> regex.search(r"^(\((?1)*\))(?1)*$", "()(") is not None
False
>>> regex.search(r"^(\((?1)*\))(?1)*$", "(((())())") is not None
False