原来文本匹配的方式一直是用中规中矩的正则来做,最近在实际生产中由于数据量骤升,现有数据量提高了大约 3-4 倍,原本使用正则处理已经到了瓶颈,这次又有增量对生产来说可谓雪上加霜,而且随着正则词越加越多,匹配效率也越来越差,数据量的激增再加上正则词越加越多,提升生产的匹配效率已是迫在眉睫。
最近一段时间我也一直再搞这部分,现在初见成效,在测试新方法匹配过程中,发现有的长正则匹配效率甚至提高了 100 倍,而且是越长文本 越长正则 提升越高。
本次就来聊聊这次优化正则的经历,需要代码的朋友直接到文末下载即可。
1 准备阶段:AC多模匹配
在谈优化正则前,我们先要知道 AC多模匹配 的概念,AC 多模匹配重点在于 字典树 和 它的失败节点匹配算法(KMP模式匹配),字典树我们都很熟悉,假设有 "aaa ,abc,bcd,cab,cad" 这几个字符串需要存储,它们在字典树中的位置这里以一张图做个简单的示意:
而设置失败指针后的示意图如下所示:
可以看到通过AC多模的方式进行匹配明显比普通遍历式查找效率要高,它将查找方式变为纵向,并且失败指针的引入使得一条分支匹配失败后不用再回到起点,顺着失败指针继续查找,如果沿着失败指针一直找到根节点都没找到,那说明在字典树中肯定没有这个字符。
2 改造阶段:正则拆分
正则拆分举例:
长正则实例(截取了代码中的一部分):
.*(网站|中断|网络传输|非正常(停|死)机|异常(停|死)机|滥用.{0,4}职权|why.?china|(翻译|拼写|书写|标志|标示|导航)(错误|不清楚|不清晰|无法辨别|模糊)){6,}.*