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

如何实现列表间前缀模糊匹配并区分匹配与未找到项

前缀模糊匹配问题修复

需求说明

对to_search列表中的每个值,在choices列表中执行严格前缀模糊匹配(仅认可前缀顺序完全一致的匹配),返回result列表中对应的项;无匹配项时显示NOT FOUND。

原代码问题

原代码使用rapidfuzz的process.extractOne和fuzz.WRatio,存在两个核心问题:

  • 误匹配:例如38050被错误匹配到358,不符合前缀匹配要求
  • 未匹配项标识错误:例如49185、51078错误匹配到1,未返回NOT FOUND

原代码:

from rapidfuzz import process, fuzz

choices = [
        '237','1721','124622','334','124624','124','1246','1876','358',
        '33751','33679','599','61','230','31','65','1721','1','124623'
    ]

result = [
            'NAD','ATE','STA','SSI','GYP','RIC','EEC','AND','GIU','ANC',
            'PAI','GAR','TAL','ANI','LAN','TRI','GDO','MAR','EDE'
        ]

to_search = ['18763044','187635','23092','3162','38050','33','49185','51078','1246','1721']

for element in to_search:
    match =  process.extractOne(element, choices, scorer=fuzz.WRatio)
    print(element,result[match[2]],'         ## ',match)

当前错误输出

18763044    AND         ##  ('1876', 90.0, 7)
187635      AND         ##  ('1876', 90.0, 7)
23092       ANI         ##  ('230', 90.0, 13)
3162        LAN         ##  ('31', 90.0, 14)
38050       GIU         ##  ('358', 72.0, 8) // 应标记为NOT FOUND
33          SSI         ##  ('334', 90.0, 3)
49185       MAR         ##  ('1', 90.0, 17)  // 应标记为NOT FOUND
51078       MAR         ##  ('1', 90.0, 17)  // 应标记为NOT FOUND
1246        EEC         ##  ('1246', 100.0, 6)
1721        ATE         ##  ('1721', 100.0, 1)

解决方案

要实现严格前缀匹配,需自定义评分规则并设置匹配阈值:

  1. 自定义评分函数,仅当choice是element的前缀时计算有效分数,否则返回0
  2. 设置分数阈值,低于阈值时判定为无匹配

修改后的代码:

from rapidfuzz import process, fuzz

choices = [
        '237','1721','124622','334','124624','124','1246','1876','358',
        '33751','33679','599','61','230','31','65','1721','1','124623'
    ]

result = [
            'NAD','ATE','STA','SSI','GYP','RIC','EEC','AND','GIU','ANC',
            'PAI','GAR','TAL','ANI','LAN','TRI','GDO','MAR','EDE'
        ]

to_search = ['18763044','187635','23092','3162','38050','33','49185','51078','1246','1721']

def prefix_scorer(query, choice, **kwargs):
    # 仅当choice是query的前缀时计算分数,否则返回0
    if query.startswith(choice):
        return fuzz.WRatio(query, choice)
    return 0

for element in to_search:
    match = process.extractOne(element, choices, scorer=prefix_scorer, score_cutoff=80)
    if match:
        print(element, result[match[2]])
    else:
        print(element, "NOT FOUND")

代码解释

  • prefix_scorer函数:从根源上过滤非前缀匹配,仅当choice是query的前缀时才计算匹配分数
  • score_cutoff=80:过滤低质量匹配,无有效匹配时match为None,此时输出NOT FOUND

最终输出

18763044    AND
187635      AND
23092       ANI
3162        LAN
38050       NOT FOUND
33          SSI
49185       NOT FOUND
51078       NOT FOUND
1246        EEC
1721        ATE

内容的提问来源于stack exchange,提问作者Rasec Malkic

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 05:55:48