当我有这样的字符串时:
s1 = 'stuff(remove_me)'
我可以轻松删除括号和 using 中的文本
# returns 'stuff'
res1 = re.sub(r'\([^)]*\)', '', s1)
如此处所解释。
但是我有时会遇到这样的嵌套表达式:
s2 = 'stuff(remove(me))'
当我从上面运行命令时,我最终得到
'stuff)'
我也尝试过:
re.sub('\(.*?\)', '', s2)
这给了我相同的输出。
如何删除外括号内的所有内容 - 包括括号本身 - 以便我最终也得到
'stuff'
(这应该适用于任意复杂的表达式)?
注意:
\(.*\)
匹配左侧第一个(
,然后匹配任何0+字符(如果未启用DOTALL修饰符则换行符除外)直到last)
,并且不匹配考虑正确嵌套的括号。
要在Python中使用正则表达式正确删除嵌套括号,您可以使用简单的
\([^()]*\)
(匹配(
,然后匹配除(
和)
之外的0+个字符,然后匹配)
)
)在 while 块中使用 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'
re
匹配很急切,因此它们尝试匹配尽可能多的文本,对于您提到的简单测试用例,只需让正则表达式运行即可:
>>> re.sub(r'\(.*\)', '', 'stuff(remove(me))')
'stuff'
如果你确定括号最初是平衡的,只需使用greedy版本:
re.sub(r'\(.*\)', '', s2)
https://regex101.com/r/kQ2jS3/1
'(\(.*\))'
这捕获了
furthest
括号以及括号之间的所有内容。
您的旧正则表达式捕获第一个括号,以及
next
括号之间的所有内容。
我在这里找到了解决方案:
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
只需减去
'('
和 ')'
的累计计数:
import numpy as np
s = '()a(x(x)x)b(x)c()d()'
s_array = np.array(list(s))
mask_open = s_array=='('
mask_close = s_array==')'
result = ''.join(s_array[(np.cumsum(mask_open) - np.cumsum(mask_close) + mask_close) < 1])
这可能比其他解决方案更快。