You need to enable JavaScript to run this app. Python正则表达式删除以{{source|开头的嵌套双大括号内容
优惠活动
大模型
产品
解决方案
定价
更多

Python正则表达式删除以{{source|开头的嵌套双大括号内容

适配嵌套结构的Wiktionary source模板删除方案

原有正则失效的核心原因

你之前编写的re.sub("{{source\|.*?}}", "", line)无法正常工作,根源在于非贪婪匹配.*?}}的匹配逻辑:

  • 它会在遇到**第一个出现的}}**时就停止匹配
  • 碰到样例中{{source|内部嵌套了{{nom w pc|Chantal|Bouchard}}这类子模板时,会提前在内层模板的结束位置截断匹配,仅删除了{{source|{{nom w pc|Chantal|Bouchard}}这一小段,剩下的引用文本和外层残留的}}完全没有被覆盖,自然达不到预期的删除效果。

可行解决方案

以下两种方案都可以同时覆盖有嵌套、无嵌套的{{source|...}}块的删除需求:

方案1:多层适配的正则匹配

针对Wiktionary模板的常见嵌套深度(最多2层双大括号嵌套),可以使用适配嵌套结构的正则,无需逐字符遍历即可完成替换:

import re

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|开头,内部可包含一层双大括号嵌套,直到匹配到最外层的结束}}
pattern = r"\{\{source\|(?:[^{}]|\{\{[^{}]*\}\})*\}\}"
processed_line = re.sub(pattern, "", line)
print(processed_line)
# 初步输出:# Test is a cool word .

该正则同样可以处理无嵌套的简单source块,比如输入# Test is a cool word {{source|Nicolas|Daniel, Presses de l'Université de Montréal 4}},处理后会直接删除整个source块,仅保留前面的文本内容。

方案2:逐字符深度追踪(适配任意层数嵌套)

如果碰到嵌套层数不确定、结构复杂的模板,逐字符遍历的方法不会出现匹配偏差,可靠性更高:

def remove_wiktionary_source(text):
    result = []
    index = 0
    text_length = len(text)
    while index < text_length:
        # 检测到 {{source| 模板起始位置
        if text[index:index+9] == "{{source|":
            brace_depth = 1
            index += 9
            # 逐字符扫描,追踪双大括号的嵌套深度
            while index < text_length and brace_depth > 0:
                if text[index:index+2] == "{{":
                    brace_depth += 1
                    index += 2
                elif text[index:index+2] == "}}":
                    brace_depth -= 1
                    index += 2
                else:
                    index += 1
            # 整个source块扫描完成,跳过块内所有内容,不加入最终结果
        else:
            result.append(text[index])
            index += 1
    return "".join(result)

# 测试用例
line1 = "# 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}}."
line2 = "# Test is a cool word {{source|Nicolas|Daniel, Presses de l'Université de Montréal 4}}"
print(remove_wiktionary_source(line1))
# 初步输出:# Test is a cool word .
print(remove_wiktionary_source(line2))
# 输出:# Test is a cool word

小提示:替换完成后如果出现单词和后续标点之间的多余空格(比如原句结构为「word 空格 {{source|...}} 标点」,删除模板后会留下「word 空格 标点」的结构),可以通过简单的空格清理处理,比如执行processed_line = re.sub(r'\s+([.,!?;:])', r'\1', processed_line),把标点前的多余空格去掉,得到和预期完全一致的输出# Test is a cool word.。


内容的提问来源于stack exchange,提问作者kavaliero

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.12 00:06:09