该正则表达式匹配字符串总是超时,是否存在写法问题?
问题根源
你遇到的是正则的灾难性回溯问题,根本原因是你的正则存在大量重叠的匹配分支,加上外层的贪婪量词,匹配失败时引擎需要遍历指数级的路径尝试匹配,最终触发超时。
原因拆解
你使用的正则为:/^[a-z0-9]((-?[a-z0-9]+)|(\.?[a-z0-9]+))*$/
存在的问题如下:
- 括号内的两个分支
(-?[a-z0-9]+)和(\.?[a-z0-9]+)匹配范围高度重叠:当内容都是小写字母/数字时,两个分支都可以命中 - 外层的
*量词允许括号内的分支重复任意次,同一段纯字母数字串可以被拆成无数种匹配组合 - 你的测试串末尾存在不符合规则的
=,引擎在最终返回不匹配前,会穷尽所有可能的拆分方式做尝试,字符串越长,需要尝试的路径数量就会指数级上升,直接导致超时。
优化方案
如果你的匹配规则是:字符串仅由小写字母、数字、连字符-、点.组成,且连字符、点不能连续出现、也不能出现在首尾,可直接使用无回溯歧义的优化版正则:/^[a-z0-9]+([-.][a-z0-9]+)*$/
该正则的逻辑完全覆盖你原有正则的合法匹配场景,同时不存在重叠分支,匹配失败时会立刻返回结果,不会出现超时问题,测试你给出的样例串时会直接返回不匹配。
内容的提问来源于stack exchange,提问作者itman_wei
相关产品推荐
相关产品推荐

