5

次のコードがあります。

        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);
        } 

私が達成しようとしているのは、検索語の前に 1 ~ 6 語、検索語の後に 1 ~ 6 語を取得することです。コードを実行すると、for ループ「matches.Count」でパフォーマンスが低下します。非常に大きな文字列では、実行に 1 分以上かかります。問題を解決するために何をすべきか、その理由について混乱しています。

4

3 に答える 3

11

カウントを見つけるには、それらをカウントするためにすべての一致を見つける必要があります。いずれにせよ 3 秒後に停止することを考えると、それは少し無意味に思えます。

の遅延評価を LINQMatchCollectionのメソッドと組み合わせて使用​​し、最初の 3 つの一致のみを取得します。Take通常StringBuilder、ループ内でも文字列連結ではなく使用することをお勧めします。

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

(StringBuilder変更はおそらくここでは大きな違いをもたらさないでしょうが、慣れるには良い習慣です。ジェネリック型でのみ機能するCastため、このメソッドは必須です。)Enumerable.TakeIEnumerable<T>

于 2013-08-25T06:57:08.020 に答える