基于Python正则按上下文替换所有格代词的技术需求
需求:基于上下文替换西班牙语所有格代词
需要补全Python代码中的匹配规则与替换逻辑,实现以下文本替换规则:
- 从左到右遍历文本,替换所有所有格代词「sus」或「su」(不区分大小写)
- 若代词前方最近位置存在
((PERSON)人名)标签:移除代词,保留后续关联信息,末尾追加((CONTEXT) de 人名) - 若代词前方无任何
((PERSON)人名)标签:移除代词,保留后续关联信息,末尾追加((CONTEXT) NO DATA)
原代码框架
import re # example 1 input_text = "((PERSON)María Rosa) ((VERB)pasará) unos dias aqui, hay que ((VERB)mover) sus cosas viejas de aqui, ya que sus cosméticos ((VERB)estorban) si ((VERB)estan) tirados por aquí. ((PERSON)Cyntia) es una buena modelo, su cabello es muy bello, hay que ((VERB)lavar) su cabello" # example 2 input_text = "Sus útiles escolares ((VERB)estan) aqui, me sorprende que ((PERSON)Juan Carlos) los haya olvidado siendo que suele ((VERB)ser) tan cuidadoso con sus útiles." # I need replace "sus" or "su" but under certain conditions subject_capture_pattern = r"\(\(PERSON\)((?:\w\s*)+)\)" # 捕获PERSON标签内的人名 associated_info_capture_pattern = r"(?:sus|su)\s+((?:\w\s*)+)(?:\s+(?:del|de )|\s*(?:\(\(VERB\)|[.,;]))" # 捕获代词后的关联信息 identification_pattern = replacement_sequence = input_text = re.sub(identification_pattern, replacement_sequence, input_text, flags = re.IGNORECASE)
预期输出
示例1输出
"((PERSON)María Rosa) ((VERB)pasará) unos dias aqui, hay que ((VERB)mover) cosas viejas ((CONTEXT) de María Rosa) de aqui, ya que cosméticos ((CONTEXT) de María Rosa) ((VERB)estorban) si ((VERB)estan) tirados por aquí. ((PERSON)Cyntia) es una buena modelo, cabello ((CONTEXT) de Cyntia) ((VERB)es) muy bello, hay que ((VERB)lavar) cabello ((CONTEXT) de Cyntia)"
示例2输出
"útiles escolares ((CONTEXT) NO DATA) ((VERB)estan) aqui, me sorprende que ((PERSON)Juan Carlos) los haya olvidado siendo que suele ((VERB)ser) tan cuidadoso con útiles ((CONTEXT) de Juan Carlos)."
解决方案
由于Python原生re.sub无法直接回溯查找最近的PERSON标签,我们改用遍历匹配+回调逻辑实现需求,补全后的完整代码如下:
import re def replace_possessive(match_info, last_person): # 获取代词后的关联信息 related_info = match_info.group(1) # 根据最近人名生成对应替换内容 if last_person: return f"{related_info} ((CONTEXT) de {last_person})" else: return f"{related_info} ((CONTEXT) NO DATA)" def process_text(input_text): last_person = None result_parts = [] # 同时匹配PERSON标签和sus/su+关联信息的正则 combined_pattern = re.compile( r"(\(\(PERSON\)((?:\w\s*)+)\))|(?:sus|su)\s+((?:\w\s*)+)(?=\s+(?:del|de )|\s*(?:\(\(VERB\)|[.,;]))", re.IGNORECASE ) last_match_end = 0 for match in combined_pattern.finditer(input_text): # 拼接匹配区间前的原始文本 result_parts.append(input_text[last_match_end:match.start()]) if match.group(1): # 匹配到PERSON标签,更新最近人名 last_person = match.group(2).strip() result_parts.append(match.group(1)) else: # 匹配到目标代词,执行替换逻辑 replaced_content = replace_possessive(match, last_person) result_parts.append(replaced_content) last_match_end = match.end() # 拼接剩余未处理的文本 result_parts.append(input_text[last_match_end:]) return ''.join(result_parts) # 测试示例1 input_text_1 = "((PERSON)María Rosa) ((VERB)pasará) unos dias aqui, hay que ((VERB)mover) sus cosas viejas de aqui, ya que sus cosméticos ((VERB)estorban) si ((VERB)estan) tirados por aquí. ((PERSON)Cyntia) es una buena modelo, su cabello es muy bello, hay que ((VERB)lavar) su cabello" print(process_text(input_text_1)) # 测试示例2 input_text_2 = "Sus útiles escolares ((VERB)estan) aqui, me sorprende que ((PERSON)Juan Carlos) los haya olvidado siendo que suele ((VERB)ser) tan cuidadoso con sus útiles." print(process_text(input_text_2))
代码说明
- 遍历匹配逻辑:通过
finditer逐个扫描文本中的PERSON标签和目标代词,实时记录最近出现的人名 - PERSON标签处理:每次匹配到
((PERSON)人名)时,更新last_person变量为当前人名 - 代词替换处理:匹配到
sus/su+关联信息时,根据last_person是否存在生成对应((CONTEXT))标签内容,同时移除原代词 - 文本拼接:将未匹配的原始文本、处理后的PERSON标签、替换后的内容拼接为最终结果
内容的提问来源于stack exchange,提问作者Matt095
相关产品推荐
相关产品推荐

