为何正则捕获组未按限定条件终止,反而捕获至行尾?
问题解决:正则捕获组未按终止条件停止匹配
核心问题分析
你的正则存在三个关键问题:
- 终止元素列表未按长度排序,导致短短语(如
sobre)优先匹配,覆盖了长短语(如por sobre) place_reference的匹配逻辑没有排除终止元素,即使是非贪婪模式,也会因为字符范围包含终止元素的部分字符而持续匹配到行尾- 起始位置断言
(?:(?<=\s)|^)无法正确处理带空格的副词(如al rededor)
修正方案
步骤1:排序短语列表
先对副词和终止元素按长度降序排序,确保多词短语优先匹配,避免短匹配截断长短语。
步骤2:重构place_reference匹配规则
使用否定前瞻限制匹配范围,确保匹配内容不会触及任何终止元素:
place_reference = r"(?:(?!{limiting_pattern})[\w\s,;.:])+"
这里的{limiting_pattern}是终止元素的正则化表示,用于排除所有终止元素的开头。
步骤3:调整正则模式结构
修正起始断言,同时明确分组逻辑,确保正确捕获副词、目标内容和终止元素。
完整修正代码
import re input_text = "((PL_ADVB)alrededor (NOUN)(del auto rojizo, algo grande y completamente veloz)). Luego dentro del baúl rápidamente abajo de una caja por sobre ello vimos una caña." 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", ".", ":", ";", ",", "(", ")", "[", "]", "¿", "?", "¡", "!", "&", "="] # 按长度降序排序,确保多词短语优先匹配 list_all_adverbs_of_place_sorted = sorted(list_all_adverbs_of_place, key=lambda x: -len(x)) list_limiting_elements_sorted = sorted(list_limiting_elements, key=lambda x: -len(x)) # 构建终止元素的正则模式,用于否定前瞻 limiting_pattern = '|'.join(re.escape(x) for x in list_limiting_elements_sorted) # 重构place_reference:匹配任何不触及终止元素的内容 place_reference = rf"(?:(?!{limiting_pattern})[\w\s,;.:])+" # 构建最终正则模式 pattern = re.compile( rf"(?:(?<=\s)|^)({'|'.join(re.escape(x) for x in list_all_adverbs_of_place_sorted)})" rf"(\s+{place_reference})?\s*({limiting_pattern})", flags=re.IGNORECASE ) # 修正替换逻辑,处理place_reference为空的情况 def replace_match(m): adv = m.group(1) ref = m.group(2).strip() if m.group(2) else " NO_DATA" terminator = m.group(3) return f"((PL_ADVB){adv}{ref}){terminator}" input_text = re.sub(pattern, replace_match, input_text) print(repr(input_text))
输出结果
'((PL_ADVB)alrededor ((NOUN)del auto rojizo, 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
相关产品推荐
相关产品推荐

