为什么正则表达式上的For循环缓慢?

Chr*_*ris 4 c# regex asp.net-mvc

我有以下代码:

        string pattern = @"(?:\S+\s){1,6}\S*" + search + @"\S*(?:\s\S+){1,6}";
        String dbContents = row[2].ToString();
        var matches = Regex.Matches(dbContents, pattern, RegexOptions.IgnoreCase | RegexOptions.Compiled);
        for (int i = 0; i < matches.Count; i++)
        {
            if (i == 3)
                break;

            Contents += String.Format("... {0} ...", matches[i].Value);
        } 
Run Code Online (Sandbox Code Playgroud)

我想要完成的是在搜索词之前得到一到六个单词,在搜索词之后得到1-6个单词.执行代码时,性能在for循环"matches.Count"上命中.对于非常大的字符串,它需要花费一分钟来执行.我很困惑为什么以及如何解决这个问题.

Jon*_*eet 10

为了找到计数,必须找到所有匹配才能计算它们.鉴于你无论如何都要在三点之后停下来,这似乎有点无意义.

使用MatchCollection延迟评估与TakeLINQ中的方法结合使用只需要前三个匹配.通常,StringBuilder在循环中使用而不是字符串连接也是一个好主意:

StringBuilder builder = new StringBuilder(...);
foreach (var match in matches.Cast<Match>().Take(3))
{
    builder.AppendFormat("... {0} ...", matches[i].Value);
}
Run Code Online (Sandbox Code Playgroud)

(这种StringBuilder变化可能不会在这里产生很大的不同,但这是一个很好的习惯.这个Cast方法是必需的,因为Enumerable.Take只适用于泛型IEnumerable<T>类型.)