Python正则匹配异常:无法完整移除not后的目标短语
正则语句的问题分析及修正方案
场景与需求
现有Pandas DataFrame示例:
import pandas as pd data = {'technician_verbatim': ["not leak not secured not fitted not parameter"]} Delta_Claims = pd.DataFrame(data)
另有匹配前缀列表 tmp_list = ['leak', "secu", "fitt", "para", "secur", "fitte", "param"],以及例外词表:
data = {'not_exceptions': ["secure","secured","fit","fitted"]} not_no_without_exceptions = pd.DataFrame(data)
需求:移除technician_verbatim中"not"后不在例外词表的词汇,保留例外词(如"not secured"、"not fitted"),预期输出为"not secured not fitted"。
当前正则仅能移除"not param",残留"eter",正则语句为:
pattern = rf'\bnot\s+{escaped_i}\s*|\b{escaped_i}\s*'
正则存在的核心问题
- 仅匹配子串而非完整单词:
escaped_i对应tmp_list里的前缀(比如"para"),正则只会移除"not para"这部分,而"parameter"剩下的"meter"不属于匹配范围,因此残留。 - 匹配逻辑割裂:正则拆分成
\bnot\s+{escaped_i}\s*和\b{escaped_i}\s*两个分支,前者只处理"not+前缀"的局部,后者处理单独的前缀子串,完全没关联"not"和后面的整个单词,导致无法完整移除"not parameter"这类短语。 - 未排除例外词的匹配:正则没有区分例外词和非例外词,可能误匹配到例外词的前缀(比如"secu"对应"secured"),但实际需要保留这类例外短语。
修正方案
要实现需求,需匹配"not"后接以tmp_list元素为前缀、且不在例外词表中的完整单词,再移除整个"not+单词"组合:
- 先将例外词转为集合,方便快速判断:
import re exceptions = set(not_no_without_exceptions['not_exceptions'])
- 构建精准匹配的正则模式:
# 转义前缀列表中的特殊字符,避免正则语法冲突 prefix_pattern = '|'.join(re.escape(p) for p in tmp_list) # 匹配"not+空格"后接非例外词、且以前缀开头的完整单词 pattern = rf'\bnot\s+(?!({"|".join(re.escape(e) for e in exceptions)}))({prefix_pattern})\w*\b'
- 执行替换并清理多余空格:
Delta_Claims['technician_verbatim'] = Delta_Claims['technician_verbatim'].str.replace(pattern, '', regex=True) # 去除首尾空格及中间多余空格 Delta_Claims['technician_verbatim'] = Delta_Claims['technician_verbatim'].str.strip().str.replace('\s+', ' ', regex=True)
执行后即可得到预期结果:"not secured not fitted"
内容的提问来源于stack exchange,提问作者Jawed Sheikh
相关产品推荐
相关产品推荐

