如何用Spacy Matcher匹配间隔任意词数的法语否定句模式
优化spaCy Matcher提取含"mais"的法语否定句
我明白你现在的痛点——重复写相同的POS规则来适配不同间隔的词确实太冗余了,spaCy的Matcher其实提供了更简洁的方式来处理这类“任意数量匹配”的需求,核心就是用好**OP参数**。
先理清Matcher的OP参数用法
你之前尝试过{}但只匹配单个词,是因为没结合正确的OP标记:
OP: "*":匹配0次或多次(对应你要的“0到任意数量间隔词”)OP: "+":匹配1次或多次(对应你问的“固定部分和最后一部分之间间隔1个或多个词”)OP: "?":匹配0次或1次(就是你之前用的,但只适合最多1个词的情况)
优化你的匹配模式
原来的pattern0里重复了5次相同的POS规则,现在可以直接替换成一个带OP: "*"的条目,同时保留标点的匹配规则,优化后的pattern如下:
pattern0 = [ {"POS": "ADV"}, # 对应否定词ne/n' {"POS": {"IN": ["AUX","VERB"]}}, {"LEMMA": {"IN": ["pas", "plus", "aucun", "rien"]}}, # 替换重复规则:匹配0到任意数量指定POS的词 {"POS": {"IN": ["ADJ", "AUX", "VERB", "NOUN", "ADV","PRON", "PROPN"]}, "OP": "*"}, {"IS_PUNCT": True, "OP": "*"}, # 匹配0到任意数量标点 {"LOWER": "mais"} ]
为什么这样改可行?
- 单个
{"POS": ..., "OP": "*"}就能覆盖0到N个符合POS要求的词,不管句子中间隔多少个词都能匹配 - 标点部分的
OP: "*"也兼容了有没有标点、多个标点的情况(比如原句里的括号、引号)
测试修改后的代码
把这个pattern替换到你的代码里,运行后依然能匹配你原来所有的测试句子,还能适配更长的间隔情况,比如你原来的句子Les hommes et les femmes ne sont pas pareils comme d'autres, mais on n'y comprend rien.,现在会正确匹配从ne到mais的所有内容,不需要再手动加重复的规则。
补充:匹配1到任意数量间隔词的情况
如果你的场景需要固定模式某部分和mais之间必须至少有1个词,只需要把对应的OP: "*"改成OP: "+"即可,比如:
# 否定结构和mais之间至少有1个指定POS的词 pattern_with_min_one = [ {"POS": "ADV"}, {"POS": {"IN": ["AUX","VERB"]}}, {"LEMMA": {"IN": ["pas", "plus", "aucun", "rien"]}}, {"POS": {"IN": ["ADJ", "AUX", "VERB", "NOUN", "ADV","PRON", "PROPN"]}, "OP": "+"}, {"IS_PUNCT": True, "OP": "*"}, {"LOWER": "mais"} ]
这样就能过滤掉否定结构直接跟mais的句子(比如je ne crois pas mais ce n'est pas ça这种,如果你不需要匹配这类的话)。
内容的提问来源于stack exchange,提问作者kely789456123
相关产品推荐
相关产品推荐

