如何在Python spaCy中构造支持OR/AND逻辑的模式匹配规则
spaCy匹配器实现无顺序约束的OR/AND短语匹配的方案
完全可以在spaCy的匹配框架里实现这类逻辑,完全不用硬套原生正则转写,还能复用spaCy自带的分词、词形归一、词性标注能力,比纯正则匹配的鲁棒性强很多。
OR逻辑(集合内任意短语出现即判定匹配)
这类逻辑和PhraseMatcher的原生机制天生适配,不需要额外写复杂判断,实现步骤非常直接:
- 把OR规则里的所有短语,通过
nlp.pipe(or_phrases)批量转成spaCy可识别的Doc格式匹配项 - 初始化
PhraseMatcher的时候把这些Doc作为同一类规则批量注册进去 - 对目标文本完成匹配后,只要匹配返回结果非空,就代表文本中出现了短语集合里的任意一个词,完全符合OR逻辑要求。
你之前示例里提到的正则逻辑(?=.*love)|(?=.*live)本质就是OR规则,用PhraseMatcher实现时不会限制短语出现的位置,只要文本全域内存在对应短语,就会被正常检索到。
AND逻辑(集合内所有短语必须全部出现,不限制出现顺序)
因为这类逻辑不要求短语的出现先后顺序,没法靠单条Matcher规则直接输出正确结果,有两种实操方案可以选:
- 轻量实现方案:先把目标文本经过小写归一、词形还原处理后,整理成一个去重的词集合,直接判断AND规则里的每一个短语是不是都在这个集合内。如果所有短语都能匹配上,就返回匹配成功;只要缺任意一个,就返回None。这种方法代码量最少,不需要写复杂的匹配规则。
- 基于Matcher的实现方案:给Matcher分别注册对应每个目标短语的独立匹配规则(比如要匹配
love和live的AND规则,就分别注册匹配love、匹配live的两个独立token规则)。等文本匹配完成后,统计所有命中的目标短语种类数,如果种类数和AND规则的短语总个数一致,就代表文本同时包含了所有要求的短语,满足匹配要求。
需要避开的坑:别想着用单条Matcher规则把不同位置的短语串起来实现AND匹配,这种写法会强制要求短语的出现先后顺序,完全不符合“不限制顺序”的要求,必须用拆分独立规则、最后统计命中覆盖度的思路做。
匹配效果对应你的示例场景
按照你给出的示例待检测文本和规则做验证:
- 当OR规则为
[efficient, design]时,因为文本全域内没有出现这两个词,匹配结果为None - 当AND规则为
[love, live]时,因为两个目标词都没有在文本中出现,匹配结果为None - 如果调整OR规则为
[programming, code],因为文本中确实出现了这两个词,OR规则会直接返回匹配成功
内容的提问来源于stack exchange,提问作者Shivadeepthi Chilukuri
相关产品推荐
相关产品推荐

