【问题标题】:A speedy way to match a text to multiple regex pattern一种将文本与多个正则表达式模式匹配的快速方法
【发布时间】:2015-11-06 07:17:54
【问题描述】:

我有大约 50000 个关键字应用了正则表达式模式。我的应用程序获取了一些文本内容并尝试查找与此内容相关的关键字。

我这样做是为了遍历所有关键字并在内容中搜索每个关键字。

因为要匹配的内容太多,如果存在我愿意找到更好的方法。

有没有更好的方法呢?

这是我目前正在做的示例代码:

 List<string> keywords = getKeywords();
        string textToMatch = getNews();

        List<string> result = new List<string>();

        foreach (var keyword in keywords)
        {
            Match r =  Regex.Match(textToMatch, keyword);
            if(r.Success)
                result.Add(keyword)
        }

【问题讨论】:

  • 我想你最好在Code Review部分问。
  • @Handoko.Chen 不。这不适合代码审查,因为这里没有要审查的代码!
  • @Handoko.Chen 因为你,我分享了一个示例代码。现在等待您的建议:)
  • @mareva 我不是 RE 方面的专家,事实上我讨厌它,因为它很慢。但我看到你使用 Regex 类的静态方法。我读到有一种方法可以加快 Regex 调用。请参阅 this articlethis article。或者,如果字符串很简单,您可以使用常规字符串方法。请参阅this article 了解正则表达式和字符串方法之间的比较。
  • 为什么要使用正则表达式?如果关键字是纯文本,那么使用if(textToMatch.Contains(keyword)){result.Add(keyword);} 可能会更快。

标签: c# regex matching keyword-search


【解决方案1】:

首先,您可以使用RegexOptions.Compiled,它指示正则表达式引擎使用轻量级代码生成将正则表达式表达式编译为IL。程序将启动较慢,但使用正则表达式的匹配更快。

下一步将是消费者生产者设计模式的一些很好的实现。遗憾的是,我不知道您的操作中最慢的是什么,但如果您尝试实现这种模式,它应该会更快(下面有一些伪代码)

        BlockingCollection<string> collection = new BlockingCollection<string>();
        Action productionAction = () =>
        {
           //produce data then
            collection.Add(ProcessedData);
        };
        Action consumentAction = () =>
        {
           //consume data
            var data = collection.Take();
            //then
            //do your things

        };
        Parallel.Invoke(productionAction,consumentAction);
        // code will end here when everything will be processed
        // also you can change Action to TaskRun to use some Multithreading

您还可以尝试使用Parallel.ForEach 替换循环来显着提高性能的最简单方法(或不!我不了解您的其余代码!)

【讨论】:

  • 我尝试了你在这里所说的一切。并行函数效果很好,但是因为我已经在多线程工作了,cpu已经很忙了,所以没有任何收益。
【解决方案2】:

如果我们认为只有一个文本可以匹配多个关键字,那么就没有完全不同的工作方式。我们可以只使用Parallel.For,编译正则表达式等。

就我而言,我收到的短信太多,无法与关键字匹配。假设我有 50 个文本和 50000 个关键字。通常我会为每个文本进入关键字循环。现在,首先我将所有文本合并为一个大文本。然后为它运行匹配。将返回匹配的关键字列表。最后,再次为每个文本运行匹配,但仅针对匹配的关键字列表。

【讨论】:

  • 这没有回答问题。我知道您正在回答自己的问题,但请添加更多详细信息,以便其他人可以通过了解您所做的工作而受益。
  • @AdrianHHH 感谢您的建议。我添加了更多信息。我可以根据需要做更多的事情。
猜你喜欢
  • 2020-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-08
  • 2014-04-10
  • 1970-01-01
  • 1970-01-01
  • 2014-08-22
相关资源
最近更新 更多