Python中的正则表达式:删除方括号及括号内部分。

5

我有一个维基百科的转储文件,但是无法找到适当的正则表达式模式来删除表达式中的双方括号。以下是表达式的示例:

line = 'is the combination of the code names for Herbicide Orange (HO) and Agent LNX, one of the [[herbicide]]s and [[defoliant]]s used by the [[United States armed forces|U.S. military]] as part of its [[herbicidal warfare]] program, [[Operation Ranch Hand]], during the [[Vietnam War]] from 1961 to 1971.'

我想删除所有带有以下条件的方括号:

  • 如果方括号内没有竖线分隔符,则删除方括号。

    例如:[[herbicide]]s 变成 herbicides

  • 如果方括号内有竖线分隔符,则删除方括号并仅使用分隔符后面的短语。

    例如:[[United States armed forces|U.S. military]] 变成 U.S. military

我尝试使用 re.matchre.search,但未能得到所需的输出结果。

谢谢你的帮助!

3个回答

13

你需要的是re.sub函数。请注意,方括号和管道符都是元字符,因此需要进行转义。

re.sub(r'\[\[(?:[^\]|]*\|)?([^\]|]*)\]\]', r'\1', line)

替换字符串中的\1指的是括号内匹配到的内容,这些括号不以?:开头(即任何情况下你想要的文本)。

有两个注意事项。这只允许在打开和关闭括号之间有一个管道符。如果有多个,则需要指定您想要第一个后面的所有内容还是最后一个后面的所有内容。另一个注意事项是,不允许单个]在打开和关闭括号之间。如果这是问题,仍然会有一个正则表达式的解决方案,但它会更加复杂。

有关该模式的完整解释:

\[\[        # match two literal [
(?:         # start optional non-capturing subpattern for pre-| text
   [^\]|]   # this looks a bit confusing but it is a negated character class
            # allowing any character except for ] and |
   *        # zero or more of those
   \|       # a literal |
)?          # end of subpattern; make it optional
(           # start of capturing group 1 - the text you want to keep
    [^\]|]* # the same character class as above
)           # end of capturing group
\]\]        # match two literal ]

我相信你需要使用\\1,否则它会打印一个八进制字符。 - Nick Garvey
谢谢!我尝试了原始表达式和带有\\1的表达式。我使用Python 2.7并且出现以下错误: raise error, v # invalid expression sre_constants.error: nothing to repeat不知道这是为什么? - notrockstar

3
>>> import re
>>> re.sub(r'\[\[(?:[^|\]]*\|)?([^\]]*)]]', r'\1', line)
'is the combination of the code names for Herbicide Orange (HO) and Agent LNX, one of the herbicides and defoliants used by the U.S. military as part of its herbicidal warfare program, Operation Ranch Hand, during the Vietnam War from 1961 to 1971.'

解释:

\[\[       # match two opening square brackets
(?:        # start optional non-capturing group
   [^|\]]*   # match any number of characters that are not '|' or ']'
   \|        # match a '|'
)?         # end optional non-capturing group
(          # start capture group 1
   [^\]]*    # match any number of characters that are not ']'
)          # end capture group 1
]]         # match two closing square brackets

通过用捕获组1的内容替换上述正则表达式的匹配项,你将获得方括号内的内容,但仅包括分隔符之后的内容(如果存在)。

3
您可以使用re.sub来查找位于[[]]之间的所有内容,我认为最好使用lambda函数来进行替换(从最后一个“|”开始获取所有内容)。
>>> import re
>>> re.sub(r'\[\[(.*?)\]\]', lambda L: L.group(1).rsplit('|', 1)[-1], line)
'is the combination of the code names for Herbicide Orange (HO) and Agent LNX, one of the herbicides and defoliants used by the U.S. military as part of its herbicidal warfare program, Operation Ranch Hand, during the Vietnam War from 1961 to 1971.'

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