You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 19:50:23