从字符串中删除括号中的内容

4

我有一个字符串,它长这样:

s = 'word1 word2 (word3 word4) word5 word6 (word7 word8) word9 word10'

如何删除括号中的所有内容,以便输出为:
'word1 word2 word5 word6 word9 word10'

我尝试了正则表达式,但好像不起作用。有什么建议吗?

最好的, Jacques


6
你尝试了哪个正则表达式没有起作用? - Fred Foo
5个回答

7
import re
s = re.sub(r'\(.*?\)', '', s)

请注意,这只会删除括号内的所有内容。这意味着在“word2和word5”之间将保留双空格。终端输出如下:
>>> re.sub(r'\(.*?\)', '', s)
'word1 word2  word5 word6  word9 word10'
>>> # -------^ -----------^ (Note double spaces there)

然而,您提供的输出并非如此。要去除额外的空格,您可以执行以下操作:
>>> re.sub(r'\(.*?\)\ *', '', s)
'word1 word2 word5 word6 word9 word10'

一个原始字符串可能会更安全:r'\(.*?\)',即使它仍然可以工作。 - ngn
我同意。它们都应该是原始字符串。谢谢。我已经更新了答案。 - Susam Pal
这个代码完美地运行了,但是为什么呢?我想到的是:s = re.sub('\(.*\)', '', s)问号的作用是什么? - Jacques Knie
Jacques,( 在正则表达式字符串中有特殊含义。(.*) 是一个分组。因此,你需要用反斜杠转义 ( 来消除其特殊含义,使其被视为要匹配的字面字符 ( - Susam Pal
@Jacques:只使用 .* 将匹配所有内容,包括右括号。在末尾加上 ? 后,它变成了“非贪婪模式”,当剩余的正则表达式可以匹配时(即下一个是右括号),它将停止消耗。在这种特殊情况下,[^)]* 是另一种选择。 - user395760

2

我的解决方案更好,只是因为它删除了额外的空格字符 ;-)

re.sub( "\s\(.*?\)","",s)

编辑:您说得对,它不能捕捉所有情况。当然,我可以编写更复杂的表达式,尝试考虑更多细节:

re.sub( "\s*\(.*?\)\s*"," ",s)

现在,result是一个期望的字符串或者如果原始字符串被括号和空格限制,则为空格。

你的解决方案不够好,因为它没有捕获所有情况:'(hello) there' :) - tzot

0
你应该用空字符串替换所有这个正则表达式的出现: \([^\)]*\)

如果您需要实际的代码,请在此处给我留言,我会添加它。 - ngn

0

你可以逐个字符地处理它。如果你保留一个字符串作为结果字符串,一个字符串作为丢弃字符串,并且一个布尔值表示你是否正在删除。

然后,对于每个字符,如果布尔值为真,则将其添加到删除字符串中;如果为假,则将其添加到实际字符串中。如果是开括号,则将其添加到删除字符串中并将布尔值设置为true;如果是闭括号,则将删除字符串设置为空字符串并将布尔值设置为false。

最后,如果有括号打开但未关闭,则会在结尾处留下一个删除字符串。

如果你想处理多个括号,请使用一个整数计数器来记录你已经打开但未关闭的括号数量,而不是使用布尔值。


0
如果你的行的格式总是像你展示的那样,你可能可以尝试不使用正则表达式:
>>> s.replace('(','').replace(')','')
'word1 word2 word3 word4 word5 word6 word7 word8 word9 word10'

这比正则表达式快4倍

>>> t1 = timeit.Timer("s.replace('(','').replace(')','')", "from __main__ import s")
>>> t2 = timeit.Timer("sub(r'\(.*?\)\ *', '', s)", "from __main__ import s; from re import sub")
>>> t1.repeat()
[0.73440917436073505, 0.6970294320000221, 0.69534249907820822]
>>> t2.repeat()
[2.7884134544113408, 2.7414613750137278, 2.7336896241081377]

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