从字符串中删除最后一个括号内的文本

3
我想知道如何从给定字符串中删除最后一次出现的()及其内容。

下面的代码会删除字符串中的所有()。
bracketedString     = '*AWL* (GREATER) MINDS LIMITED (CLOSED)'
nonBracketedString  = re.sub("\s\(.*?\)", '', bracketedString)
print(nonBracketedString1)

我希望能得到以下输出结果。
*AWL* (GREATER) MINDS LIMITED

你为什么要使用正则表达式呢?只需定位最后一个花括号,如果找到,则将其删除即可。 - Ulrich Eckhardt
1
那些不是花括号。 - Paul Panzer
值得注意的是,你刚刚拿出了“正则语言无法解析的事物”的最著名的例子,并询问如何使用正则表达式解析它们。当然,re可以做比实际正则语言更多的事情,而且您的数据可能有某些使得即使使用严格的正则表达式也可以做到这一点的特殊条件(例如,您的圆括号不能嵌套,或只能嵌套到3个层次等),但仍然是一个很好的迹象,说明您可能在这里使用了错误的工具。 - abarnert
2个回答

7
你只能在字符串末尾有前导空格的情况下删除 (...) 子字符串:
\s*\([^()]*\)$

请查看正则表达式演示.

详细信息

  • \s* - 0个或多个空白字符
  • \( - 一个(
  • [^()]* - 除()之外的0个或多个字符
  • \) - 一个)
  • $ - 字符串的结尾。

请查看Python演示:

import re
bracketedString     = '*AWL* (GREATER) MINDS LIMITED (CLOSED)'
nonBracketedString  = re.sub(r"\s*\([^()]*\)$", '', bracketedString)
print(nonBracketedString) # => *AWL* (GREATER) MINDS LIMITED

使用PyPi正则表达式模块,您还可以删除字符串末尾的嵌套括号:
import regex
s = "*AWL* (GREATER) MINDS LIMITED (CLOSED(Jan))" # => *AWL* (GREATER) MINDS LIMITED
res = regex.sub(r'\s*(\((?>[^()]+|(?1))*\))$', '', s)
print(res)

请参阅Python演示

详细信息

  • \s* - 0个或多个空白字符
  • (\((?>[^()]+|(?1))*\)) - 第1组:
    • \( - 一个 (
    • (?>[^()]+|(?1))* - 1个或多个不包括()的字符或整个第1组模式的重复
    • \) - 一个 )
  • $ - 字符串结尾。

这个代码可以正常工作,但我想删除最后一组括号内的所有内容。例如,如果我输入 'AWL (GREATER) MINDS LIMITED (CLOSED(Jan))',那么它就无法正常工作... - VKB
@VKB请查看更新后的答案,其中包含一个去除字符串末尾嵌套括号的示例。 - Wiktor Stribiżew

1
如果您想替换括号的最后一个出现位置,即使它们不在字符串的结尾:
*AWL* (GREATER) MINDS LIMITED (CLOSED) END

您可以使用淬火贪婪令牌
>>> re.sub(r"\([^)]*\)(((?!\().)*)$", r'\1', '*AWL* (GREATER) MINDS LIMITED (CLOSED) END')                        
# => '*AWL* (GREATER) MINDS LIMITED  END'  

演示

说明:

  • \([^)]*\) 匹配括号内的字符串
  • (((?!\().)*)$ 确保直到字符串末尾没有其他开放括号

    • (?!\() 是负向先行断言,检查后面没有 (
    • . 匹配下一个字符(由于负向先行断言,它不能是 (
    • (((?!\().)*)$ 整个序列重复直到字符串末尾 $ 并保留在捕获组中
  • 我们用第一个捕获组 (\1) 替换匹配项,该捕获组保留了括号后面的匹配项

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接