Cle*_*leb 6 python regex parentheses
当我有这样的字符串:
s1 = 'stuff(remove_me)'
Run Code Online (Sandbox Code Playgroud)
我可以轻松删除括号和使用中的文本
# returns 'stuff'
res1 = re.sub(r'\([^)]*\)', '', s1)
Run Code Online (Sandbox Code Playgroud)
为解释在这里.
但我有时遇到这样的嵌套表达式:
s2 = 'stuff(remove(me))'
Run Code Online (Sandbox Code Playgroud)
当我从上面运行命令时,我最终得到了
'stuff)'
Run Code Online (Sandbox Code Playgroud)
我也尝试过:
re.sub('\(.*?\)', '', s2)
Run Code Online (Sandbox Code Playgroud)
这给了我相同的输出.
如何删除外括号内的所有内容 - 包括括号本身 - 以便我最终得到'stuff'
(这应该适用于任意复杂的表达式)?
Wik*_*żew 10
注意:\(.*\)
匹配(
左边的第一个,然后匹配任何0+个字符(如果未启用DOTALL修改器,则除了换行符)到最后一个 )
,并且不考虑正确嵌套的括号.
与Python中的正则表达式正确删除嵌套的括号,则可以使用一个简单的\([^()]*\)
(匹配(
,然后0+比其它字符(
和)
,然后)
在a)中,而使用块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
Run Code Online (Sandbox Code Playgroud)
基本上:删除(...)
no (
和)
inside,直到找不到匹配项.用法:
print(remove_text_between_parens('stuff (inside (nested) brackets) (and (some(are)) here) here'))
# => stuff here
Run Code Online (Sandbox Code Playgroud)
非正则表达方式也是可能的:
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'
Run Code Online (Sandbox Code Playgroud)
如前所述,您需要一个递归正则表达式来匹配任意级别的嵌套,但是如果您知道最多只能嵌套一个级别,请尝试以下模式:
\((?:[^)(]|\([^)(]*\))*\)
Run Code Online (Sandbox Code Playgroud)
[^)(]
匹配不是括号的字符(否定的类)。|\([^)(]*\)
或与另一(
)
对内含任何数量的非 内含物)(
。(?:
... )*
所有这些时间都在里面(
)
在[^)(]
不带+
量词的替换之前,如果不平衡,则失败更快。
您需要添加可能发生的更多级别的嵌套。例如,最多2个级别:
\((?:[^)(]|\((?:[^)(]|\([^)(]*\))*\))*\)
Run Code Online (Sandbox Code Playgroud)
re
匹配是渴望的,因此它们尝试匹配尽可能多的文本,对于您提到的简单测试用例,只需让正则表达式运行:
>>> re.sub(r'\(.*\)', '', 'stuff(remove(me))')
'stuff'
Run Code Online (Sandbox Code Playgroud)