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

如何在Django查询中使用正则表达式获取路径的最短匹配结果

解决方案

你的查询逻辑方向搞反了,__icontains是判断dir_id字段包含给定路径,实际你需要的是给定路径匹配dir_id的通配规则,再取最短的匹配即可。

方案1:用SQL LIKE实现(性能更好)

利用Postgres的REPLACE函数把dir_id里的*替换为SQL通配符%,再判断给定路径是否匹配该模式,最后按dir_id长度升序排序取第一条就是最短匹配:

from django.db.models import Func, F, Value, CharField, Length

given_path = "Abcd/dir1/dir2"

access_obj = Access.objects.annotate(
    dir_pattern=Func(
        F('dir_id'),
        Value('*'),
        Value('%'),
        function='REPLACE',
        output_field=CharField()
    )
).filter(
    given_path__like=F('dir_pattern')
).order_by(
    Length('dir_id')
).first()

如果你的Django版本低于3.2,不支持filter左侧放常量,可以用extra实现:

given_path = "Abcd/dir1/dir2"
access_obj = Access.objects.extra(
    where=['%s LIKE REPLACE(dir_id, \'*\', \'%\')'],
    params=[given_path]
).order_by('LENGTH(dir_id)').first()

方案2:用正则匹配实现

如果需要用正则的话,把dir_id里的*替换为正则通配符.*即可,逻辑和上面一致:

from django.db.models import Func, F, Value, CharField, Length

given_path = "Abcd/dir1/dir2"
access_obj = Access.objects.annotate(
    regex_pattern=Func(
        F('dir_id'),
        Value('*'),
        Value('.*'),
        function='REPLACE',
        output_field=CharField()
    )
).filter(
    given_path__regex=F('regex_pattern')
).order_by(
    Length('dir_id')
).first()

内容的提问来源于stack exchange,提问作者Souvik Ray

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 03:48:04