【问题标题】:Regular expression in python: removing brackets with brackets insidepython中的正则表达式:删除带有括号的括号
【发布时间】:2020-12-21 17:37:49
【问题描述】:

我有一个维基词典,正在努力寻找合适的正则表达式模式来删除表达式中的双括号。以下是表达式的示例:

line = "# Test is a cool word {{source|{{nom w pc|Chantal|Bouchard}}, ''La langue et le nombril'', Presses de l'Université de Montréal (PUM), 2020, p. 174}}."

我希望删除所有以 {{source|:

开头的括号

例如:# Test is a cool word.

我尝试使用 re.sub 像这条线 = re.sub("{{source\|.*?}}", "", line )

但我得到了# Test is a cool word, ''La langue et le nombril'', Presses de l'Université de Montréal (PUM), 2020, p. 174}}.

我也可以有这样的句子line = "# Test is a cool word {{source|Nicolas|Daniel, Presses de l'Université de Montréal 4}}"

感谢您的帮助!

【问题讨论】:

  • 你的意思是你只想用re库来做这件事吗?如果您需要正则表达式,最好使用 PyPi 正则表达式库。
  • 如何使用 PyPi 正则表达式?我没用过
  • 在最后一个 }} 之后可以保留要保留的文本,或者每个句子可以有多个匹配项吗?

标签: python python-3.x regex mediawiki python-re


【解决方案1】:

您可以安装 PyPi 正则表达式库(在终端/控制台中输入 pip install regex 并按 ENTER),然后使用

import regex
rx = r"\s*{{source\|(?>[^{}]|({{(?:[^{}]++|(?1))*}}))*}}\s*"
line = "# Test is a cool word {{source|{{nom w pc|Chantal|Bouchard}}, ''La langue et le nombril'', Presses de l'Université de Montréal (PUM), 2020, p. 174}}."
print( regex.sub('', line) )
# => # Test is a cool word.

请参阅Python demo。 正则表达式是

\s*\{\{source\|(?>[^{}]|(\{\{(?:[^{}]++|(?1))*}}))*}}\s*

请参阅regex demo。详情:

  • \s* - 零个或多个空格
  • {{source\| - 文字 {{source| 字符串
  • (?>[^{}]|({{(?:[^{}]++|(?1))*}}))* - 零次或多次重复:
    • [^{}] - { 和 } 以外的字符
    • | - 或
    • ({{(?:[^{}]++|(?1))*}}) - 第 1 组(递归是必需的):{{,除 {{ 和 }} 或第 1 组递归之外的任何一个或多个字符出现零次或多次,然后是 }}字符串
  • }} - }} 字符串
  • \s* - 零个或多个空格。

【讨论】:

    【解决方案2】:

    .*?}} 子表达式将找到以}} 结尾的最短可能字符串。如果你想跳过成对的{{...}},你必须这样说。

    re.sub(r"\{\{source\|(?:\{\{.*?\}\})*.*?\}\}", "", line)
    

    还请注意,如果您想扩展它以处理其他级别的嵌套,您也必须明确说明;正则表达式确实不是处理嵌套结构的适当工具,尤其是不是任意嵌套结构。 (这是common FAQ.)

    【讨论】:

      【解决方案3】:

      您可以不使用正则表达式并涵盖所有级别的嵌入式元数据。

      line = "# Test is a cool word {{source|{{nom w pc|Chantal|Bouchard}}, ''La langue et le nombril'', Presses de l'Université de Montréal (PUM), 2020, p. 174}}."
      
      from itertools import accumulate
      levels = accumulate( (c=="{")-(p=="}") for c,p in zip(line," "+line) )
      result = "".join(c for c,level in zip(line,levels) if level==0)
      
      print(result)
      # Test is a cool word .
      

      这会计算嵌入的增量“级别”,每个“{”都会上升,每个“}”会下降。零级字符是实际文本的一部分,其他所有字符都被排除在外。

      【讨论】:

        【解决方案4】:

        您可以使用以下正则表达式来获得所需的答案。

        \W+{{source\|.*}}
        

        代码将是,

        re.sub("\W+{{source\|.*}}", "", line )
        

        除了?,正则表达式与问题中的几乎相同。删除? 使其尽可能多次匹配.。

        此外,要删除{{}} 之前的空格,请添加\W+。

        【讨论】:

        • 如果文本有多个 {{source|...}} 出现,这将吃掉第一个和最后一个之间的所有文本。
        猜你喜欢
        • 2020-02-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-26
        • 2018-08-25
        • 1970-01-01
        相关资源
        最近更新 更多