运行以下代码时,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)
{
...
}
知道如何加快速度吗?
答案 0 :(得分:2)
将RegexOptions.None | RegexOptions.Multiline | RegexOptions.IgnoreCase
更改为RegexOptions.Compiled
会产生相同的结果(因为您的模式不包含任何文字字母或^
/ $
)。
在我的机器上,这会将您链接的样本文档所花费的时间从46秒减少到21秒(这对我来说似乎仍然很慢,但对您来说可能已经足够了)。
编辑:所以我对此进行了一些调查并发现了真正的问题。
问题在于你的正则表达式的前半部分:\w+([-.]\w+)*\.\w+([-.]\w+)*@
。这在匹配实际包含@
符号的输入部分时效果很好,但对于仅匹配\w+([-.]\w+)*\.\w+([-.]\w+)*
但不是后跟@
的部分,正则表达式引擎浪费了大量时间回溯并从序列中的每个位置重试(并再次失败,因为仍然没有@
!)
您可以使用\b
强制匹配从字边界开始来解决此问题:
string pattern = @"\b\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*";
在您的示例文档中,这会在1秒内生成相同的10个结果。
答案 1 :(得分:0)
尝试将regex
用于streams
,使用 mono-project regex
,这篇文章对.Net
并尝试提高您的正则表达能力。
答案 2 :(得分:0)
要回答如何更改它,您需要告诉我们它应该匹配的内容。
问题可能在最后一部分@\w+([-.]\w+)*\.\w+([-.]\w+)*
。在字符串“bla@a.b.c.d.e-f.g.h”上,它必须尝试许多可能性,直到找到匹配为止。
可能有点Catastrophic Backtracking。
因此,您需要以更好,更“独特”的方式定义模式。你真的需要“Dash / dot - dot - dash / dot”吗?