You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使含捕获组的Regex仅匹配未被((NOUN))包裹的文本

解决正则误替换((NOUN)包裹区域内内容的问题

现有Python正则代码会错误地对((NOUN)和))包裹区域内的文本执行替换,比如将((NOUN)(del auto rojizo, dentro de algo grande y completamente veloz))修改为((NOUN)(del auto rojizo, ((PL_ADVB)dentro de algo grande y completamente veloz))),不符合预期。我们需要调整正则逻辑,仅在该包裹区域外进行捕获替换,最终得到正确的输出结果。

修改后的完整代码

import re

input_text = "((PL_ADVB)alrededor ((NOUN)(del auto rojizo, dentro de algo grande y completamente veloz)). Luego dentro del baúl rápidamente abajo de una caja por sobre ello vimos una caña." #example input

place_reference = r"(?i:[\w,;.]\s*)+?"
list_all_adverbs_of_place = ["adentro", "dentro", "al rededor", "alrededor", "abajo", "hacía", "hacia", "por sobre", "sobre"]
list_limiting_elements = list_all_adverbs_of_place + ["vimos", "hemos visto", "encontramos", "hemos encontrado", "rápidamente", "rapidamente", "intensamente", "durante", "luego", "ahora", ".", ":", ";", ",", "(", ")", "[", "]", "¿", "?", "¡", "!", "&", "="]

# 构建正则:要么匹配((NOUN)...))块,要么匹配目标地点副词模式
noun_block_pattern = r"\(\(NOUN\)\(.*?\)\)"
target_pattern = r"(?:(?<=\s)|^)({})(\s+{})(?=\s*({}))".format(
    '|'.join(re.escape(x) for x in list_all_adverbs_of_place),
    place_reference,
    '|'.join(re.escape(x) for x in list_limiting_elements)
)
pattern = re.compile(rf"({noun_block_pattern})|({target_pattern})", flags=re.IGNORECASE | re.DOTALL)

def replace_match(match):
    if match.group(1):
        # 匹配到NOUN包裹块,直接返回原内容
        return match.group(1)
    else:
        # 匹配到目标模式,执行原替换逻辑
        advb = match.group(3)
        ref = match.group(4)
        follow = match.group(5)
        return f"((PL_ADVB){advb}{ref}){follow}" if ref else f"((PL_ADVB){advb} NO_DATA){follow}"

input_text = re.sub(pattern, replace_match, input_text)

print(repr(input_text))

关键改动说明

  1. 正则分支设计:将正则拆分为两个分支,第一个分支精准匹配((NOUN)(...))格式的包裹块(使用re.DOTALL让.匹配换行符,确保跨行也能正确识别);第二个分支保留原有的地点副词匹配逻辑。
  2. 替换回调函数:在re.sub中使用自定义函数,判断匹配结果:如果是NOUN包裹块则直接返回原内容,不做修改;如果是目标地点副词模式,则按照原逻辑添加((PL_ADVB))标记。
  3. 调整捕获组顺序:因为新增了NOUN块的捕获组,所以需要调整后续捕获组的索引,确保替换时取到正确的内容。

执行上述代码后,将得到预期输出:

'((PL_ADVB)alrededor ((NOUN)(del auto rojizo, dentro de algo grande y completamente veloz)). Luego ((PL_ADVB)dentro del baúl) rápidamente ((PL_ADVB)abajo de una caja) ((PL_ADVB)por sobre ello) vimos una caña.'

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 15:30:22