Spacy中IS_DIGIT与LIKE_NUM对特定字符识别异常求助
Spacy LIKE_NUM匹配数字后缀异常问题
你遇到的问题核心是Spacy的分词规则和LIKE_NUM属性的判定逻辑导致的:
先看你的示例文本被Spacy分词后的结果,打印每个token的text和LIKE_NUM属性:
nlp = spacy.load("en_core_web_sm") doc = nlp("1231M 1232G 1233H 1234J 1235V 1236T") for token in doc: print(token.text, token.like_num)
输出会是:
1231 True M False 1232 True G False 1233H False 1234J False 1235V False 1236 True T False
原因
- Spacy的分词器会把带M/G/T的字符串拆成「数字+后缀」两个token,因为这些是英文里常见的数量单位(M=百万、G=十亿、T=万亿),属于默认的分词拆分规则。拆分后的数字token是纯数字,
LIKE_NUM自然为True,所以能被你的匹配器捕捉到。 - 而H/J/V不属于Spacy默认识别的数量单位,所以整个
1233H这类字符串会被当成一个单独的token,这个token不是纯数字,也不符合LIKE_NUM的内置规则(内置规则只识别纯数字、带常见单位的数字表达等),因此匹配不到。
解决方案
根据你的需求,有两种简单的处理方式:
方式1:用正则匹配包含数字+字母的完整token
直接修改匹配模式,用正则匹配所有以数字开头、后跟大写字母的token:
nlp = spacy.load("en_core_web_sm") matcher = Matcher(nlp.vocab) # 匹配数字+大写字母的完整token pattern = [{'TEXT': {'REGEX': r'^\d+[A-Z]$'}}] matcher.add("DIGIT", [pattern]) doc = nlp("1231M 1232G 1233H 1234J 1235V 1236T") matches = matcher(doc, as_spans=True) for span in matches: print(span.text, span.label_)
这样就能匹配到所有1231M、1232G、1233H等完整字符串。
方式2:匹配数字token+指定后缀token
如果需要单独提取数字部分,同时兼容指定的后缀,可以修改模式为匹配「数字token+指定后缀token」:
nlp = spacy.load("en_core_web_sm") matcher = Matcher(nlp.vocab) # 匹配数字token + 指定后缀token的组合 pattern = [{'LIKE_NUM': True}, {'TEXT': {'IN': ['M','G','T','H','J','V']}}] matcher.add("DIGIT_SUFFIX", [pattern]) doc = nlp("1231M 1232G 1233H 1234J 1235V 1236T") matches = matcher(doc, as_spans=True) for span in matches: print(span.text, span.label_)
这个方式会匹配到1231M、1232G等组合,你可以通过span[0].text单独获取数字部分。
内容的提问来源于stack exchange,提问作者CodeTripper
相关产品推荐
相关产品推荐

