首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Python 用 difflib 实现模糊查询

Python 用 difflib 实现模糊查询

作者头像
小田测测看
发布2026-06-17 17:21:08
发布2026-06-17 17:21:08
930
举报

在处理文本匹配时,正则表达式这类 “硬匹配” 方式,面对拼写错误、细微差异容易失效。而 Python 中的 difflib 库,能很好地弥补这一短板,实现更贴合实际场景的模糊查询,比如处理用户输入难免出错的搜索需求。

前序

正则表达式(Regex)在文本匹配中常用,但面对拼写错误时很 “脆弱”。例如想匹配 “iPhone 16 Pro Max”,若查询词是 “iphone 16 prro max”(“max” 错写为 “mmax” ),正则因严格字符匹配,无法识别,最终无结果返回,如下代码示例:

代码语言:javascript
复制
import re
products = ["iPhone 16 Pro Max", "vivo", "xaiomi"]
query = "iphone 16 pro mmax"  # 存在拼写错误
pattern = re.compile(query, re.IGNORECASE)
matches = [p for p in products if pattern.search(p)]
print(matches)  # 输出 []

difflib 里的 SequenceMatcher 是关键工具,通过计算序列相似度,判断文本间的相似程度示例:

代码语言:javascript
复制
from difflib import SequenceMatcher

def fuzzy_match(query, products, threshold=0.6):
    matches = []
    for product in products:
        # 统一转小写,避免大小写干扰匹配
        ratio = SequenceMatcher(None, query.lower(), product.lower()).ratio()  
        if ratio >= threshold:  # 设定阈值,过滤相似度低的结果
            matches.append((product, f"{ratio:.2f}"))  
    return matches

query = "iphone 16 pro mmax"
products = ["iPhone 16 Pro Max", "vivo", "xaiomi"]
print(fuzzy_match(query, products))  
# 输出 [('iPhone 16 Pro Max', '0.88')],匹配成功 

ratio() 返回 0 - 1 的值,值越接近 1 代表越相似

引申

速度更快的

SequenceMatcher 还有 quick_ratio() 方法,计算速度更快(精度稍降)。若处理几万条商品名等大数据量场景,用 quick_ratio 可提升效率,示例:

代码语言:javascript
复制
ratio = SequenceMatcher(None, query.lower(), product.lower()).quick_ratio()
加权匹配

商品名里的品牌、型号(如 iPhone 14 )比后缀(Pro Max )更重要。可拆分字符串关键部分,给不同部分设权重,再结合 difflib 得分,让匹配更贴合业务,比如:

代码语言:javascript
复制
def weighted_fuzzy_match(query, products, threshold=0.6):
    matches = []
    for product in products:
        # 拆分关键部分,假设按空格拆分,品牌、型号为前几个元素
        query_parts = query.lower().split()
        product_parts = product.lower().split()
        # 给品牌、型号部分更高权重(这里简单示例,实际可更复杂)
        weight = 1
        iflen(query_parts) >= 2andlen(product_parts) >= 2:
            if query_parts[0] == product_parts[0] and query_parts[1] == product_parts[1]:
                weight = 2
        ratio = SequenceMatcher(None, query.lower(), product.lower()).ratio() * weight
        if ratio >= threshold * weight:
            matches.append((product, f"{ratio:.2f}"))
    return matches
处理多语言 / 特殊字符

若文本含 emoji、外语字符(如 Samsung Galaxy S23 里的 Galaxy ),可先简单清洗(保留核心字符,去掉无意义符号),再用 difflib 匹配,避免特殊字符干扰,示例(简单清洗特殊字符):

代码语言:javascript
复制
import re

defclean_text(text):
    # 保留字母、数字、空格,去掉其他特殊字符
    return re.sub(r'[^\w\s]', '', text)

deffuzzy_match_with_clean(query, products, threshold=0.6):
    cleaned_query = clean_text(query)
    matches = []
    for product in products:
        cleaned_product = clean_text(product)
        ratio = SequenceMatcher(None, cleaned_query.lower(), cleaned_product.lower()).ratio()
        if ratio >= threshold:
            matches.append((product, f"{ratio:.2f}"))
    return matches

difflib 无需额外安装,轻量够用,日常简单模糊匹配需求,用它就很合适。

#Python #Python模糊匹配

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-08-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 编程拾光 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前序
  • 引申
    • 速度更快的
    • 加权匹配
    • 处理多语言 / 特殊字符
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档