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.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の結果が生成されます。

于 2012-10-10T06:10:35.607 に答える
0

regexforを使用してみてstreamsmono-project regexを使用してください。この記事は次の場合に役立ちます。.Net

正規表現のパフォーマンスを改善してみてください。

于 2012-10-10T06:12:19.520 に答える
0

それを変更する方法に答えるには、何を一致させるべきかを教えていただく必要があります。

問題はおそらく最後の部分にあり@\w+([-.]\w+)*\.\w+([-.]\w+)*ます。文字列 "bla@abcde-fgh" では、一致するものが見つかるまで、多くの可能性を試す必要があります。

壊滅的なバックトラッキングの少しである可能性があります。

したがって、より優れた「独自の」方法でパターンを定義する必要があります。「ダッシュ/ドット - ドット - ダッシュ/ドット」が本当に必要ですか?

于 2012-10-10T06:21:16.953 に答える