timi
V2EX  ›  问与答

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

  •  1
     
  •   timi · Jan 13, 2022 · 4615 views
    This topic created in 1754 days ago, the information mentioned may be changed or developed.

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

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

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

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

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

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

    虽然编译要跑一个小时,但是运行快啊(
    wszgrcy
    wszgrcy
    Jan 13, 2022
    17
    把 1w 个正则合并成一个正则,让引擎自己优化?[doge]
    litmxs
    litmxs
    Jan 13, 2022 via Android
    18
    试试 Intel 的 hyperscan ,多模正则库
    Chinsung
    Chinsung
    Jan 13, 2022
    19
    给正则构建一个树,一万个正则之间肯定有互斥的和包含关系,根据正则之间的关系简单分组,在正则树上匹配查找。
    SteveWoo
    SteveWoo
    Jan 13, 2022
    20
    弄 1w 台主机,发给 1w 个主机,算完了给你结果
    popvlovs
    popvlovs
    Jan 13, 2022
    21
    hyperscan
    jianhua
    jianhua
    Jan 13, 2022
    22
    包括:
    1. 缓存匹配结果和类型。记录上次匹配结果和特征,引入特征查找算法。
    2. 通过分析正则的含义,打标签(数字、字母、字符等匹配规则):
    2.1 通过建立离线测试集,暴力测试正则的匹配含义
    2.2 通过分析正则语法
    基于正则的标签,优化原始数据特征提取和检索算法。最简单的,当你知道输入字符串是一个数字,那么应该排除掉所有字母、字符类的正则。
    timi
    timi
    OP
    Jan 13, 2022
    23
    @GeruzoniAnsasu 感觉路子很野但是又很有道理😂
    timi
    timi
    OP
    Jan 13, 2022
    24
    @murmur 其实不是路由,更接近于给某个 URL 贴个标签这样的,场景比较特殊不变透露但基本就是酱紫
    paopjian
    paopjian
    Jan 14, 2022
    25
    @GeruzoniAnsasu 第一次看到这么厉害的库,英语都没怎么读懂,好难
    seanzxx
    seanzxx
    Jan 14, 2022
    26
    @GeruzoniAnsasu 我也是第一时间想到了 ragel ,以前拿这个来重写了一堆手写的正则匹配,真的很好用
    yesterdaysun
    yesterdaysun
    Jul 7, 2023
    27
    合并正则+多线程
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1311 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 64ms · UTC 21:03 · PVG 05:03 · LAX 13:03 · JFK 16:03
    ♥ Do have faith in what you're doing.