有 1 个输入字符串,和 1 万个正则,如何找到哪个正则匹配 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
timi
V2EX    问与答

有 1 个输入字符串,和 1 万个正则,如何找到哪个正则匹配

  •  1
     
  •   timi 2022 年 1 月 13 日 3878 次点击
    这是一个创建于 1497 天前的主题,其中的信息可能已经有所发展或是发生改变。

    循环 1 万次是不是性能很 low ,有什么优化解吗

    27 条回复    2023-07-07 09:52:41 +08:00
    icyalala
        1
    icyalala  
       2022 年 1 月 13 日
    看着很奇葩的问题啊,最初的需求是什么?
    murmur
        2
    murmur  
       2022 年 1 月 13 日
    应该是敏感词过滤吧,
    这个只能老老实实匹配,漏一个问题就大了,不要想着诀窍,真出了问题大事
    timi
        3
    timi  
    OP
       2022 年 1 月 13 日
    @icyalala 类似于根据不同的 URL 进行路由,但是简单的字符串匹配满足不了……
    ebingtel
        4
    ebingtel  
       2022 年 1 月 13 日
    搞个多进程的 daemon 服务,每个进程负责 部分正则
    dallaslu
        5
    dallaslu  
       2022 年 1 月 13 日
    如果不是正则的话,可以构造一个包含一万个节点的匹配树。如果是正则的话,好像也有可能啊,怕不是要自己魔改一个正则实现来构造匹配树
    nekoneko
        6
    nekoneko  
       2022 年 1 月 13 日
    多线程并发呗
    java 直接 parallelStream
    ch2
        7
    ch2  
       2022 年 1 月 13 日
    与每个模式串的复杂度有关,如果模式串复杂度都很低,那么 1 万次匹配也是秒出
    dallaslu
        8
    dallaslu  
       2022 年 1 月 13 日
    chihiro2014
        9
    chihiro2014  
       2022 年 1 月 13 日
    前缀树?
    murmur
        10
    murmur  
       2022 年 1 月 13 日
    @dallaslu AC 自动机不能完成所有东西,比如我要匹配(拼音是 sha 的所有汉字)(2-5 个任意非中文字符)(拼音为 b 的所有汉字)

    你的 AC 自动机怎么弄
    murmur
        11
    murmur  
       2022 年 1 月 13 日
    @dallaslu 回错了,我没看楼主突然回了

    路由这个东西还要自己做的,啥库不支持模糊路由啊
    shyrock
        12
    shyrock  
       2022 年 1 月 13 日   2
    正则就是匹配条件吧?所以要想保持匹配结果不变,又想提升效率。要么并行、要么提升单次匹配的效率。
    对了,还有一个思路是利用已经匹配的正则所加入的信息,也就是说要先分析这一万个正则的相关性,把匹配 A 的必然匹配 B 这种关系找出来;或者匹配 C 的必然不匹配 D 。这样可以构建一个匹配的顺序,尽量减少匹配次数。
    lianyue
        13
    lianyue  
       2022 年 1 月 13 日
    如果只需要某一个匹配的结果那

    吧 10000 个正则 合并成 一个正则 用 `|` 分开 并且每个正则分组好(?<id1>正则规则 1) (?<id2>正则规则 2)
    然后 响应结果 看哪个下标不为 null 就知道是哪个正则匹配成功了
    ys2016814
        14
    ys2016814  
       2022 年 1 月 13 日
    FST
    lianyue
        15
    lianyue  
       2022 年 1 月 13 日
    (?<id1>原始的正则规则 1)|(?<id2>原始的正则规则 2)
    GeruzoniAnsasu
        16
    GeruzoniAnsasu  
       2022 年 1 月 13 日   6
    …… 你应该尝试把那 1w 个正则编译到一起去

    既然是路由分发,那么这些正则就必然是静态的,你完全可以把时间都放到编译期。
    之前做过一些极重规则的东西,数以万计内置规则,我们用了这个
    http://www.colm.net/open-source/ragel/

    虽然编译要跑一个小时,但是运行快啊(
    wszgrcy
        17
    wszgrcy  
       2022 年 1 月 13 日
    把 1w 个正则合并成一个正则,让引擎自己优化?[doge]
    litmxs
        18
    litmxs  
       2022 年 1 月 13 日 via Android
    试试 Intel 的 hyperscan ,多模正则库
    Chinsung
        19
    Chinsung  
       2022 年 1 月 13 日
    给正则构建一个树,一万个正则之间肯定有互斥的和包含关系,根据正则之间的关系简单分组,在正则树上匹配查找。
    SteveWoo
        20
    SteveWoo  
       2022 年 1 月 13 日
    弄 1w 台主机,发给 1w 个主机,算完了给你结果
    popvlovs
        21
    popvlovs  
       2022 年 1 月 13 日
    hyperscan
    jianhua
        22
    jianhua  
       2022 年 1 月 13 日
    包括:
    1. 缓存匹配结果和类型。记录上次匹配结果和特征,引入特征查找算法。
    2. 通过分析正则的含义,标签(数字、字母、字符等匹配规则):
    2.1 通过建立离线测试集,暴力测试正则的匹配含义
    2.2 通过分析正则语法
    基于正则的标签,优化原始数据特征提取和检索算法。最简单的,当你知道输入字符串是一个数字,那么应该排除掉所有字母、字符类的正则。
    timi
        23
    timi  
    OP
       2022 年 1 月 13 日
    @GeruzoniAnsasu 感觉路子很野但是又很有道理
    timi
        24
    timi  
    OP
       2022 年 1 月 13 日
    @murmur 其实不是路由,更接近于给某个 URL 贴个标签这样的,场景比较特殊不变透露但基本就是酱紫
    paopjian
        25
    paopjian  
       2022 年 1 月 14 日
    @GeruzoniAnsasu 第一次看到这么厉害的库,英语都没怎么读懂,好难
    seanzxx
        26
    seanzxx  
       2022 年 1 月 14 日
    @GeruzoniAnsasu 我也是第一时间想到了 ragel ,以前拿这个来重写了一堆手写的正则匹配,真的很好用
    yesterdaysun
        27
    yesterdaysun  
       2023 年 7 月 7 日
    合并正则+多线程
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1972 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 34ms UTC 13:46 PVG 21:46 LAX 05:46 JFK 08:46
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86