1

現在、次の正規表現を使用して、Outlook HTML メール アイテムから最初の会話アイテムを削除しています。

.*?>(([^:]+?):<.*?\2):

最初の会話アイテムを削除するには、最初に出現したグループ 1 をグループ 2 の値に置き換えます。.NET では次のようになります。

private static readonly Regex LAST_CONVERSATION_REPLACE_PATTERN = new Regex(@".*?>(([^:]+?):<.*?\2):", RegexOptions.Compiled);
// ...
MatchCollection matches = LAST_CONVERSATION_REPLACE_PATTERN.Matches(htmlMessageBody);
if (matches.Count > 0)
{
    Match match = matches[0];
    if (match.Groups.Count > 2)
    {
        return htmlMessageBody.ReplaceFirst(match.Groups[1].ToString(), match.Groups[2].ToString());
    }
}

ReplaceFirst独自の文字列拡張メソッドです。ただし、このパフォーマンスは少し残念です。Regex Coach はこれを巨大なメール アイテムにマイクロ秒で適用できますが、Outlook アドインでは最大 10 秒かかります。

パターンを次の明示的な代替手段に置き換えると、パフォーマンスが大幅に向上します。

.*?>(From:<.*?From):

その正規表現を使用すると、必要なものを取得するのに 1 秒もかかりません。ただし、これは言語固有であるため、以前のバリアントを優先します。.NET で高速化する方法はありますか? または、これでより良いパフォーマンスを発揮できるサードパーティの正規表現ライブラリはありますか?

提案をありがとう

パスカル

4

2 に答える 2

1

遅さの理由が何であるかは、私にははっきりとは言えません ( Outlook のパフォーマンスが低い例のテキストを投稿していただければわかります)。

しかし、正規表現を最適化するためのアイデアがいくつかありますが、それらが大幅な改善をもたらした場合は驚くでしょう. しかし、誰が知っている - 試してみましょう。

まず、plus を遅延させる必要はありません。代わりに、所有格にするか、アトミック グループを使用することをお勧めします。また、単語の境界は、2 回目の一致に適した開始点を選択するのに役立つ場合があります。

.*?>(((?>[^:]+)):<.*?\b\2):
于 2012-07-15T16:47:05.393 に答える
0

私はそれ.*?があなたの問題を引き起こしていると確信しています。たとえば、最初のものは、正規表現を強制的に停止し、ドキュメントの先頭からすべての位置で一致を試みます。幸いなことに、とにかくその部分は必要ありません。しかし、常に頼りにするのではなく、できる限り具体的にする必要があります.*?

これを試して:

private static readonly Regex LAST_CONVERSATION_REPLACE_PATTERN 
    = new Regex(@"^(?>(\w+:).*)(?>\s+(?!^\1).*)+", RegexOptions.Multiline);

すべてのヘッダー名がそれぞれの行の先頭にあると想定しても安全だと思います。結局のところ、これは電子メールです。また、作業が非常に簡単になります。実際、それを想定できない場合は、失敗している可能性があります。

^(?>(\w+:).*)は、行頭のヘッダー名のように見えるものに一致し、.*その行の残りを消費します。これをアトミック グループに入れることで、行頭での一致の試みが正規表現の後半で失敗した場合に、行を一致させる他の方法を試すために戻ってくる必要がなくなります。

(?>\s+(?!^\1).*)行区切りと次の行を消費しますが、先読みがターゲットヘッダー名で始まっていないことを確認した後でのみです。

于 2012-07-16T17:19:59.157 に答える