使用PCRE2正则重复组匹配合法邮箱,解决正则引擎崩溃问题
问题原因分析
引擎停滞是灾难性回溯导致的:正则([a-zA-Z0-9]+.?)*结构中,组内的.是可选匹配,克林星作用于整个分组时,同一段文本可以有无数种拆分匹配方式。当遇到不符合规则的字符串(比如全是点的邮箱前缀)时,正则引擎会穷尽所有可能的匹配路径,时间复杂度飙升到指数级,最终表现为引擎停滞甚至崩溃。
正确解决方案
我们可以通过明确限定点的出现规则规避回溯问题:要求点必须出现在两个字母数字段之间,不允许连续出现、也不允许出现在段首或段尾,搭配非捕获分组减少不必要的内存开销,最终正则如下:
/^[a-zA-Z0-9]+(?:\.[a-zA-Z0-9]+)*@[a-zA-Z0-9]+(?:\.[a-zA-Z0-9]+)*\.[a-zA-Z0-9]+$/gm
规则说明
[a-zA-Z0-9]+(?:\.[a-zA-Z0-9]+)*:匹配「单个字母数字段 + 任意多个点+字母数字段」的结构,自动过滤连续点、首尾带点的非法段- 邮箱前缀用上述结构匹配,@之后的域名主体也用上述结构匹配,最后补充
\.[a-zA-Z0-9]+匹配顶级域名段,完全符合word1.word2.wordN@word1.word2.wordN.word的合法邮箱结构 - 非捕获分组
(?:)不会存储分组匹配结果,进一步提升正则运行效率,完全不会出现回溯崩溃的问题
内容的提问来源于stack exchange,提问作者JodeNgb
相关产品推荐
相关产品推荐

