在最近阅读了一种被称为“灾难性回溯”的现象之后,似乎我自己的正则表达式模式正在导致某种 CPU 问题。我使用这个表达式来扫描 100k-200k 个字符的大型 HTML 字符串。该模式匹配 IP:port 格式的 IP 地址(例如 1.1.1.1:90)。模式如下:
private static Regex regIp = new Regex(@"(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\." +
@"(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4]" +
@"[0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}" +
@"[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])\:[0-9]{1,5}",
RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant);
表达式使用如下:
MatchCollection matchCol = regIp.Matches(response);
foreach (Match m in matchCol)
{
doWorkWithMatch(m);
}
通过这个正则表达式模式运行大约 100 个字符串后,它开始阻塞计算机并使用 99% 的 CPU。有没有更合乎逻辑的方式来构造这个表达式以减少 CPU 使用率并避免回溯?我不确定是否甚至会发生回溯,或者它是否只是同时执行正则表达式评估的线程过多的问题 - 欢迎所有输入。