0

运行以下代码时,CPU 负载会上升,并且在较大的文档上需要很长时间:

string pattern = @"\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*";
Regex regex = new Regex(
      pattern,
      RegexOptions.None | RegexOptions.Multiline | RegexOptions.IgnoreCase);

MatchCollection matches = regex.Matches(input); // Here is where it takes time
MessageBox.Show(matches.Count.ToString());

foreach (Match match in matches)
{
    ...
}

知道如何加快速度吗?

4

3 回答 3

2

更改RegexOptions.None | RegexOptions.Multiline | RegexOptions.IgnoreCaseRegexOptions.Compiled产生相同的结果(因为您的模式不包含任何文字字母或^/ $)。

在我的机器上,这将您链接的示例文档所花费的时间从 46 秒减少到 21 秒(这对我来说仍然很慢,但对您来说可能已经足够了)。

编辑:所以我对此进行了更多研究,并发现了真正的问题。

问题出在你的正则表达式的前半部分:\w+([-.]\w+)*\.\w+([-.]\w+)*@. 这在匹配实际包含@符号的输入部分时效果很好,但是对于仅匹配\w+([-.]\w+)*\.\w+([-.]\w+)*但后面没有@的部分,正则表达式引擎会浪费大量时间回溯并从序列中的每个位置重试(并且再次失败,因为仍然没有@!)

您可以通过使用以下命令强制匹配从单词边界开始来解决此问题\b

 string pattern = @"\b\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*";

在您的示例文档中,这会在 1 秒内产生相同的 10 个结果。

于 2012-10-10T06:10:35.607 回答
0

尝试使用regexfor streams,使用mono-project regex,这篇文章对.Net

并尝试提高您的正则表达式性能。

于 2012-10-10T06:12:19.520 回答
0

要回答如何更改它,您需要告诉我们,它应该匹配什么。

问题可能在最后一部分@\w+([-.]\w+)*\.\w+([-.]\w+)*。在字符串“bla@abcde-fgh”上,它必须尝试多种可能性,直到找到匹配项。

可能有点灾难性的回溯

因此,您需要以更好、更“独特”的方式定义您的模式。你真的需要“破折号/点 - 点 - 破折号/点”吗?

于 2012-10-10T06:21:16.953 回答