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

2022 年 1 月 13 日
 timi

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

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

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

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

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

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

虽然编译要跑一个小时,但是运行快啊(
wszgrcy
2022 年 1 月 13 日
把 1w 个正则合并成一个正则,让引擎自己优化?[doge]
litmxs
2022 年 1 月 13 日
试试 Intel 的 hyperscan ,多模正则库
Chinsung
2022 年 1 月 13 日
给正则构建一个树,一万个正则之间肯定有互斥的和包含关系,根据正则之间的关系简单分组,在正则树上匹配查找。
SteveWoo
2022 年 1 月 13 日
弄 1w 台主机,发给 1w 个主机,算完了给你结果

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/828016

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX