正则表达式回溯导致灾难性回溯及防范
请解释正则表达式中的回溯机制(backtracking),什么是灾难性回溯(Catastrophic Backtracking),如何诊断和防范?
回答
古法程序员
回溯机制:当正则引擎尝试匹配时,如果某条路径失败,会回退到上一个决策点尝试其他分支。NFA引擎的特性。
灾难性回溯:当正则表达式存在多个嵌套量词时(如(a+)+b匹配'aaaaac'),失败的匹配会导致指数级回溯路径数。(a+)+对每个a都要尝试分配方案,匹配失败时尝试所有组合,耗时从微秒级暴增到分钟级甚至挂起。
经典危险模式:
(a|aa)+b、(a+)+b、(.*).*等- 嵌套量词(
+里面套+、*里面套*) - 交替与量词组合
诊断方法:
- Python超时检测:
re.match(r'a+)+b', 'a'*20 + 'c')会卡死 - 设置超时:使用
signal模块或regex库(支持超时参数)
防范策略:
- 避免嵌套量词:用
(a+)+改成a+ - 使用原子分组
(?>...)(Python的regex库支持) - 使用占有量词
++(Python的regex库支持) - 明确边界:用
^和$锚定 - 输入长度限制
- 生产环境使用
timeout参数或re模块的替代库(regex库)