0

HTML ドキュメントがあり、複数 (1 ~ 10k) [現時点では 1k、後で最大 10k] のキーワードの発生に対してフィルター処理したいと考えています。

次のような検索用語を保存する、コンパイル済みの正規表現があります。

static Regex r = new Regex(@"keyword1|keyword2|keyword999",RegexOptions.Compiled | RegexOptions.IgnoreCase);

これは私のコードです:

Stopwatch sw = new Stopwatch();
sw.Start();
MatchCollection matches = Cache.r.Matches(doc.DocumentNode.InnerHtml);
string s = "";
if (matches.Count > 0)
{
    foreach (Match m in matches)
    {
        s += m.Value + ",";
    }
}
long time = sw.ElapsedMilliseconds;
Console.Write(time + " = "+matches.Count+" -> "+s );

平均所要時間は約 5 ~ 8 秒です。これは多すぎます。多くのキーワードに対して HTML ドキュメントをフィルタリングする効率的な方法はありますか? または、これをフィルタリングするためのより効率的なアルゴリズムがあるかもしれません..

4

4 に答える 4

2

lboshuizen指摘したように

10kのキーワードで正規表現を作成するのは道のりではないようです[...]

複数のスレッドを生成する余裕がある場合は、ドキュメントを並行してスキャンして、キーワードの出現を確認できます。

IEnumerable<string> keywords = LoadKeywords();
List<string> list = new List<string>();
keywords.AsParallel()
    .Aggregate(list, (seed, keyword) =>
    {
        if(doc.DocumentNode.InnerHtml.Contains(keyword))
            seed.Add(keyword);
        return seed;
    });
于 2013-01-28T15:46:42.897 に答える
2

いくつかの答えはすでにかなり良いですが、これも入れようと思いました...

私は同じことを行い、HTML Agility Pack を使用して、キーワードの分析を削減しました。

http://htmlagilitypack.codeplex.com/

HTML フラグメントを取得し、テキスト ノードのみを検索して、ドキュメント全体ではなくそのスペースに対してキーワード分析を実行するのは非常に簡単です。

また、誤検知 (javascript コメント、alt タグなどに現れるキーワード) を取り除くのにも役立ちます。

検索スペースを減らしてみてください。

于 2013-01-28T15:53:17.650 に答える
2

..StringBuilderの代わりに使用する必要がありますstring

キーワードが何であるかについてもっと教えてくれなければ、最適化はほとんどありません..

于 2013-01-28T15:19:42.693 に答える
1

提案:

10k のキーワードで正規表現を作成することは、私の視点からはうまくいかないようです。正規表現は貪欲で、あらゆる種類の冗長な一致を試みます。(=無駄な時間)

より小さなキーワード セットを使用して正規表現を構築し、HTML ドキュメントでインクリメンタルに実行します。

最適化は、一致したキーワード (および関連するコンテンツ) をドキュメントから削除することです。これにより、ドキュメントが縮小され、残りの正規表現の処理が大幅に減ります == 実行が高速になります。

または

ドキュメントを再スキャンするために正規表現を使用しないでください。文書を単語に分解し、もう一度辞書で調べます。ドキュメントに 10,000 ワードすべてが含まれているとは思えません。(最小セットからのループは、最大セットからのループよりも効率的です)

于 2013-01-28T15:19:34.913 に答える