使用spaCy 2.2.0版本Matcher.add()方法时遇E171报错问题
spaCy匹配器[E171]错误解决及总统姓名提取方案
错误根源
你碰到的ValueError: [E171]错误,核心问题是调用Matcher.add()时,给on_match参数传了个列表,但这个参数只接受可调用函数(自定义回调)或者None,完全不接受列表类型。
解决方法&总统姓名提取实操
以spaCy 2.2.0版本为例,直接上可运行的代码示例:
1. 基础准备
先导入库、加载模型并初始化匹配器:
import spacy from spacy.matcher import Matcher # 加载对应版本的英文小模型 nlp = spacy.load("en_core_web_sm") matcher = Matcher(nlp.vocab)
2. 定义总统姓名匹配模式
针对"President + 姓名"的常见格式,定义匹配规则:
# 模式说明:匹配"president"词,后跟1-2个大写开头的专有名词(适配名+姓/仅姓的情况) pattern = [ {"LOWER": "president"}, {"POS": "PROPN", "IS_TITLE": True}, {"POS": "PROPN", "IS_TITLE": True, "OP": "?"} # 第二个专有名词设为可选 ]
3. 正确添加匹配器(两种方式)
方式一:不用回调,直接提取结果
如果不需要实时处理匹配结果,直接省略on_match(默认值为None):
# 第三个参数是匹配模式,on_match省略则默认None matcher.add("PRESIDENT_NAME", None, pattern) # 测试文本 doc = nlp("President Joe Biden will attend the meeting. President Trump spoke yesterday.") matches = matcher(doc) # 遍历提取匹配内容 for match_id, start, end in matches: span = doc[start:end] print(f"提取到总统姓名:{span.text}")
方式二:用自定义回调函数处理
如果需要在匹配到结果时立刻做处理,写个符合要求的回调函数(参数必须是matcher, doc, id, matches):
def get_president_name(matcher, doc, id, matches): # 取最新匹配的结果 match_id, start, end = matches[-1] span = doc[start:end] print(f"匹配到总统姓名:{span.text}") # 添加模式时传入回调函数(注意这里是传函数本身,不是列表!) matcher.add("PRESIDENT_NAME", [get_president_name], pattern) # 处理文本触发回调 doc = nlp("President Joe Biden will attend the meeting. President Trump spoke yesterday.") matches = matcher(doc)
关键提醒
- 绝对别给
on_match传列表,要么传函数,要么传None(或省略)。 - 可以根据实际文本调整模式,比如碰到带标点的情况(如"President, Joe Biden"),可以在模式里加
{"ORTH": ",", "OP": "?"}来适配。
内容的提问来源于stack exchange,提问作者K.R.M.A Productions
相关产品推荐
相关产品推荐

