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

你应该使用StringBuilder而不是string..

除非您告诉我们更多有关关键字是什么的信息,否则几乎没有任何优化..

于 2013-01-28T15:19:42.693 回答
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 回答
1

建议:

用 10k 个关键字创建一个正则表达式似乎不是我的 POV 的方法。正则表达式是贪婪的,会尝试各种冗余匹配。(=浪费时间)

使用较小的关键字集构建正则表达式并在您的 html 文档中以增量方式运行它们。

优化可以是从文档中删除匹配的关键字(和相关内容),将缩小并且剩余的正则表达式的工作更少==运行得更快。

或者

把它转过来,不要使用正则表达式来扫描文档。将文档分解为单词并再次使用字典检查它们。我怀疑该文档将包含所有 10k 个单词。(从最小集合循环比从最大集合循环更有效)

于 2013-01-28T15:19:34.913 回答