Python正则匹配含标点短语:CSV短语与语料库精确匹配问题
解决正则匹配含特殊标点短语的精确匹配问题
问题根源
你的代码错误在于没有转义短语中的正则特殊字符(如?、!、.等),这些字符会被正则引擎当作操作符解析,导致错误匹配。比如短语stop?中的?会被解释为“匹配前面的字符0次或1次”,而非作为普通标点匹配,这就会出现像They couldn't just stop?被错误统计为2次匹配的情况。
解决方案
核心步骤是对每个短语进行正则转义,确保所有特殊字符被当作普通文本处理,再实现你的两个需求:
1. 转义短语列表
首先读取CSV中的短语,用re.escape()处理每个短语,同时统一大小写保证匹配一致性:
import re # 读取CSV短语列表(根据你的实际读取逻辑调整) phrase_list = self.corpora['rhetorical_devices.csv'][0].to_list() # 转义正则特殊字符 + 统一小写 escaped_phrases = [re.escape(phrase.lower()) for phrase in phrase_list]
2. 判断是否存在匹配
构建转义后的正则模式,用re.search()检查主语料库中是否有匹配:
# 构建正则模式,用|连接所有转义后的短语 match_pattern = '|'.join(escaped_phrases) # 检查匹配并返回布尔值 has_match = bool(re.search(match_pattern, master_corpus.lower()))
3. 统计精确匹配数量
用re.findall()获取所有非重叠的精确匹配,再统计数量:
# 获取所有匹配结果并计数 match_count = len(re.findall(match_pattern, master_corpus.lower()))
额外说明
如果需要确保短语是独立的语义单元(比如避免stop匹配stopping),可以给每个转义后的短语添加单词边界\b,但注意非单词字符(如标点)会影响边界判断,可调整为用环视匹配前后的非单词字符或字符串首尾:
# 带边界的模式示例(按需选择) bound_phrases = [] for phrase in escaped_phrases: if phrase.strip().isalnum(): bound_phrases.append(fr'\b{phrase}\b') else: bound_phrases.append(phrase) match_pattern = '|'.join(bound_phrases)
内容的提问来源于stack exchange,提问作者James O'Connor
相关产品推荐
相关产品推荐

