用于锚定标记的正则表达式固定CPU

时间:2013-04-29 22:23:00

标签: c# regex performance

所以我把我的正则表达式打破了一半,发现这一半导致cpu在负载下挂起。有哪些性能储蓄者可以帮助我?我真的找不到任何可以刮去的地方。

private string pattern = 
@"(<a\s+href\s*=\s*(\""|')http(s)?://(www.)?([a-z0-9]+\-?[a-z0-9]+\.)?wordpress.org(\""|'))";

Regex wordPressPattern = new Regex(regexPattern, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);

1 个答案:

答案 0 :(得分:3)

作为性能接收器的唯一突出的是这部分:

[a-z0-9]+\-?[a-z0-9]+

我们的想法是匹配luxury-yachtTHX-1138等带连字符的字词,同时仍然允许字词不带连字符。麻烦的是,如果没有连字符,正则表达式引擎仍然必须选择如何在第一个[a-z0-9]+和第二个之间分配字符。如果它尝试将wordw-o-r-(no hyphen)-d匹配,并且正则表达式中的某些内容无法匹配,则必须返回并尝试w-o-(no hyphen)-r-d,依此类推。这些努力毫无意义,但正则表达式引擎无法知道这一点。你需要给它一些帮助,如下:

[a-z0-9]+(-[a-z0-9]+)?

现在你说,“如果用完字母数字,下一个字符是连字符,请尝试匹配更多的字母数字。否则,请继续下一部分。”但在这种情况下你不需要如此具体;您正在尝试查找网址,而不是验证网址。我建议您用以下代码替换该部分:

[a-z0-9-]+

这也允许它匹配带有多个连字符的单词(例如,james-bond,还有james-bond-007)。

您还有许多不必要的捕获组。您似乎没有使用捕获,因此您也可以使用ExplicitCapture选项来提高性能。但是,即使是纯粹的分组目的,似乎也不需要大多数群体。我建议你试试这个正则表达式:

@"<a\s+href\s*=\s*[""']https?://([a-z0-9-]+\.)+wordpress\.org[""']"

......使用以下选项:

RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture