跳到主要内容

半夜被一个正则干了三个小时

小盐啃文档
小盐啃文档

· 阅读约 3 分钟

9 月 4 号,凌晨一点二十二,客户群里甩来一句"导出又卡住了"。

我在被窝里,盯了两秒,回了句"我看下",然后爬起来开电脑。我们那个导出功能是个 Node 脚本,晚上定时跑,把某个客户的商品表导成 Excel 发群里。白天好好的,这客户的数据量最近涨了一大截。

远程连上去,日志停在"开始处理 sku"。再往下没了。CPU 那一行是红的,100%,一直不下来。进程不死,也不报错,就这么咬着。

我第一反应是内存不够。查了下,加了个 --max-old-space-size=4096,重启,跑了两分钟,还是原地卡死。又加到 8192,一样。这时候我已经有点烦了,因为加内存这种操作是我为数不多能背下来的,结果它没用。

凌晨两点,我把代码拉下来从头翻。处理 sku 那里有一段正则,是我们前任写的,注释就两个字:校验。那个正则长这样,一堆 (a+)+ 套在一起的东西,我不贴了,反正当时我盯了它半分钟没看懂谁包着谁。

我拿客户的真实数据喂进去试了一遍,字符串长到某一位数的时候,脚本直接不动了。短一点的就秒过。

就这一段。找到了,但我不懂为什么。

然后把那段报错贴给 AI,让它解释。它回了我一个词:catastrophic backtracking。catastrophic,我查了下,灾难性的。backtracking,回溯。直译过来就是"灾难性回溯",听着像什么电影名字。

大概是这个意思:正则那种嵌套的量词,遇到一段匹配到一半又不匹配的字符串,引擎会一条路一条路地往回试,试的分支数量是指数级涨。客户那段 sku 串恰好长在那个临界点上,一下就炸了。它不报错,它就在那儿老老实实地试,试到天荒地老。

我盯着"指数级"那三个字看了会儿。之前一直觉得正则就是个高级查找替换,没想到它能把我服务器干趴下。

改法其实很简单,把那个大正则拆成几个小的,顺序走,别让量词互相嵌套。我改完跑了一遍,四秒钟。四秒。

四点二十,脚本跑通,Excel 发出去了,客户群没人回,估计都睡了。

我躺下的时候在想,这事其实跟英语一毛钱关系没有,但没那个英文单词我还是得卡着。我要是自己盯着那段正则猜,大概率猜到天亮也猜不到"回溯"这上面去。有时候是一个英文词救了我,不是一个知识点救了我。这俩不太一样。

对了,catastrophic 我之前一直拼成 catastropic,少一个 h,AI 帮我把拼写也纠正了。行吧。

今日单词:catastrophic,灾难性的,第八次见它了,估计还得再见几次。

小盐啃文档
小盐啃文档

英语不好,硬啃英文文档。今日单词又忘了,明天接着查。

查看主页 →