如何删除字符串中外括号之间的所有文本?
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.
(?:
...)*
所有这一切在 (
)
中任意次数
在交替之前使用 [^)(]
没有 +
量词,如果不平衡则失败更快。
您需要添加更多可能发生的嵌套级别。例如,最多 2 个级别:
\((?:[^)(]|\((?:[^)(]|\([^)(]*\))*\))*\)
注意:\(.*\)
匹配左起第一个 (
,然后匹配任何 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'
我在这里找到了解决方案:
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
当我有这样的字符串时:
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.(?:
...)*
所有这一切在(
)
中任意次数
在交替之前使用 [^)(]
没有 +
量词,如果不平衡则失败更快。
您需要添加更多可能发生的嵌套级别。例如,最多 2 个级别:
\((?:[^)(]|\((?:[^)(]|\([^)(]*\))*\))*\)
注意:\(.*\)
匹配左起第一个 (
,然后匹配任何 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'
我在这里找到了解决方案:
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