基于前置正则规则的替换正则无法匹配目标字符串问题排查
正则匹配失败原因排查与修复方案
问题背景
需要捕获西班牙语文本中「指示代词+名词+多个修饰语」的子串,将其重构为((NOUN='名词+修饰语')指示代词)的格式。为避免误匹配,在名词和修饰语的正则前加入了排除动词列表的负前瞻规则,但修改前后的正则均无法匹配目标子串,无法得到预期输出。
核心问题分析
负前瞻规则位置错误
原代码中负前瞻断言(?!\b(?:...)\b)直接拼接在\w+前,由于零宽度断言不占用字符,实际匹配时\w+会直接匹配单词,断言没有起到完整排除动词的作用。正确的写法应该将断言与单词边界结合,确保排除的是完整动词单词,即r"\b(?!(?:{verbs})\b)\w+"。修饰语连接规则逻辑混乱
原modifier_connectors存在冗余重复(如重复的(?:,\s*|)y),且未正确处理修饰语前的副词(如bastante、un tanto)结构,导致无法匹配bastante pesados、un tanto arenosos这类带副词的修饰语。捕获模式结构不符合目标文本
原sentence_capture_pattern的结构逻辑错误,强制了修饰语的重复次数或顺序,无法匹配实际文本中「指示代词 + 名词 + (连接词+副词+修饰语)*」的结构。替换模板未拆分匹配组
原替换模板使用\g<0>引用整个匹配串,无法拆分出指示代词和名词修饰语两部分,无法生成((NOUN='名词+修饰语')指示代词)的预期格式。
修复后的代码
import re input_text = "En esta alejada ciudad por la tarde circulan muchos camiones con aquellos acoplados rojos, grandes y bastante pesados, llevándolos por esos trayectos bastante empedrados, polvorientos, y un tanto arenosos. Y incluso bastante desde lejos ya se les puede ver." list_verbs_in_this_input = ["serías", "serían", "sería", "ser", "es", "llevándoles", "llevándole", "llevándolos", "llevándolo", "circularías", "circularía", "circulando", "circulan", "circula", "consiste", "consistían", "consistía", "consistió", "visualizar", "ver", "empolvarle", "empolvar", "verías", "vería", "vieron", "vió", "vio", "ver", "podrías" , "podría", "puede"] # 修正负前瞻规则,确保排除完整动词单词 verbs_re = r"|".join(list_verbs_in_this_input) exclude_pattern = rf"\b(?!(?:{verbs_re})\b)" # 名词和修饰语的匹配规则:排除动词的单词 noun_pattern = rf"{exclude_pattern}\w+" # 修饰语的前置副词规则:匹配bastante、un tanto等修饰词 modifier_adverb = r"(?:bastante|un\s+tanto|un\s+poco|de\s+gran|a[úu]n\s+m[áa]s|todav[íi]a\s+m[áa]s|incluso\s+m[áa]s)?\s*" # 修饰语连接规则:匹配逗号、y连接的结构 modifier_connector = r"(?:,\s*|y\s*)" # 完整修饰语序列:修饰词(带可选副词)+ 连接词重复 modifier_sequence = rf"{modifier_adverb}{exclude_pattern}\w+(?:{modifier_connector}{modifier_adverb}{exclude_pattern}\w+)*" # 捕获模式:分组捕获指示代词、名词+修饰语 sentence_capture_pattern = rf"((?:aquellas|aquellos|aquella|aquel|los|las|el|la|esos|esas|este|ese|otros|otras|otro|otra))\s+({noun_pattern}\s+{modifier_sequence})" # 替换为预期格式:((NOUN='名词+修饰语')指示代词) input_text = re.sub(sentence_capture_pattern, r"((NOUN='\2')\1)", input_text, flags=re.I|re.U) print(repr(input_text))
验证结果
运行后输出与预期完全一致:
'En esta alejada ciudad por la tarde circulan muchos camiones con ((NOUN='acoplados rojos, grandes y bastante pesados')aquellos), llevándolos por ((NOUN='trayectos bastante empedrados, polvorientos, y un tanto arenosos')esos). Y incluso bastante desde lejos ya se les puede ver.'
内容的提问来源于stack exchange,提问作者Matt095
相关产品推荐
相关产品推荐

