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

如何将含数字+单位的文本拆分为三类Token以优化搜索匹配?

刚好之前做过类似的电商商品索引优化,这个问题的核心就是解决数字与单位连写/空格分隔的检索一致性问题,下面给你梳理具体的实现思路和可落地的方案:

核心逻辑

我们需要在常规分词的基础上,额外识别出「数字+单位连写」的token,拆分出独立的数字、单位token,同时保留原连写token,这样不管用户搜74Ah还是74 Ah,都能命中目标文档。

具体实现步骤

1. 先定义精准的正则匹配规则

首先要写出能覆盖绝大多数常见数字+单位组合的正则,既要匹配整数/小数,也要兼容不同格式的单位(大小写、单复数等)。

通用版正则(覆盖大多数场景)

([+-]?\d+\.?\d*)([a-zA-Z]+)
  • ([+-]?\d+\.?\d*):匹配带正负号的整数或小数(比如74、220.5、-12V里的-12)
  • ([a-zA-Z]+):匹配后续的字母单位(比如Ah、V、cm)

精准版正则(针对已知单位枚举)

如果你的业务里单位是固定的(比如只涉及电压、长度、电池容量),可以用枚举式正则避免误匹配:

([+-]?\d+\.?\d*)(V|cm|Ah|W|kg|ml|L)

2. 在分词流程中插入自定义处理

不管你用的是开源检索引擎(Elasticsearch/Solr)还是自定义索引系统,都要在常规分词之后加入这个额外处理:

  • 先执行常规分词,得到基础token列表(比如Varta、Super-charge、battery、74Ah)
  • 遍历每个token,用正则匹配是否为「数字+单位连写」模式
  • 匹配成功的话,就把捕获到的数字、单位,以及原连写token(用集合存储避免重复)加入最终token集合

3. 不同场景的落地示例

示例1:Elasticsearch 自定义分词器

在ES里可以通过自定义token_filter来实现,步骤如下:

  1. 创建包含自定义过滤器的索引设置:
{
  "settings": {
    "analysis": {
      "filter": {
        "num_unit_splitter": {
          "type": "pattern_capture",
          "preserve_original": true,
          "patterns": [
            "(\\d+\\.?\\d*)([a-zA-Z]+)"
          ]
        }
      },
      "analyzer": {
        "product_search_analyzer": {
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "num_unit_splitter"
          ]
        }
      }
    }
  }
}
  • preserve_original: true:保留原连写token(比如74ah)
  • lowercase过滤器:统一转小写,避免大小写检索差异
  • 测试这个分词器,输入Varta Super-charge battery 74Ah会得到:varta, super, charge, battery, 74ah, 74, ah

示例2:Python 自定义索引脚本

如果是自己用Python搭建索引系统,代码可以这样写:

import re

def product_tokenizer(text):
    # 常规分词(实际项目建议用spaCy/nltk等专业分词库)
    base_tokens = text.split()
    final_tokens = set(base_tokens)  # 用集合自动去重
    
    # 匹配数字+单位的正则
    num_unit_pattern = re.compile(r'([+-]?\d+\.?\d*)([a-zA-Z]+)')
    
    for token in base_tokens:
        match = num_unit_pattern.fullmatch(token)
        if match:
            num_token = match.group(1)
            unit_token = match.group(2)
            final_tokens.add(num_token)
            final_tokens.add(unit_token.lower())  # 统一转小写优化检索
    
    return list(final_tokens)

# 测试
sample_text = "Varta Super-charge battery 74Ah"
print(product_tokenizer(sample_text))
# 输出:['Varta', 'Super-charge', 'battery', '74Ah', '74', 'ah']

4. 额外优化建议

  • 单位归一化:比如把AH、Ahs统一转成ah,避免单位格式差异导致的检索失效
  • 处理特殊格式:比如带斜线的单位100km/h,可以调整正则匹配(\d+\.?\d*)([a-zA-Z/]+)
  • 避免误匹配:如果有类似abc123def的字符串,不要拆分,所以建议用fullmatch而非search来匹配整个token

内容的提问来源于stack exchange,提问作者Michal Holub

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 20:42:43