【问题标题】:Can LINQ be used to search for multiple Regex expressions in a string?可以使用 LINQ 在字符串中搜索多个 Regex 表达式吗?
【发布时间】:2018-05-05 18:27:48
【问题描述】:

我有以下有效的代码,但想使用 LINQ(或其他东西)来加快它的速度,以查找目标中是否有任何 Regex 搜索字符串。

List<Regex> Filters = new List<Regex>();
Filters.Add(new Regex("string1", RegexOptions.IgnoreCase));
Filters.Add(new Regex("string2", RegexOptions.Compile));
...
bool found = false
string target = "string which may contain string1 or string2 or neither";
foreach (Regex r in Filters) {
   if (r.IsMatch(target)) {
       found = true;
       break; // get out as soon as found
   }
}
if (found) { // do stuff }

当前搜索正在处理的大文件需要很长时间。 有没有办法让 .Any 或 .First 更有效地完成这项工作?

【问题讨论】:

  • 您是否应该并行化您的代码 (PLINQ)?
  • Linq 根本不会让你的代码更快,它只是隐藏了复杂性并引入了一些可能导致很多混淆的东西,如果你不熟悉它 - 延迟执行。简而言之:不要为了一些优化而使用 LINQ。话虽如此,您的代码已经尽可能快了,至少在您想使用正则表达式时是如此。
  • 这是对正则表达式引擎的低效使用。使用交替将两个正则表达式组合成 1 个正则表达式。 new Regex("string1|string2");
  • 如果您有 许多字符串,请使用此工具 HERE 创建一个完整的正则表达式 trie,这是最快的人类已知的搜索机制。而 HERE 它会为所有表情符号创建一个 trie。
  • Filters.Any(x => x.IsMatch(target)); ??

标签: c# regex linq


【解决方案1】:

正如所暗示的,使用 LinQ 最简单的简化可以通过 All(要求满足所有条件)或 Any(以 || 方式连接您的正则表达式条件)来实现。

List<Regex> Filters = new List<Regex>();
Filters.Add(new Regex("string1", RegexOptions.IgnoreCase, RegexOptions.Compiled));
Filters.Add(new Regex("string2", RegexOptions.Compiled));
string target = "string which may contain string1 or string2 or neither";
if (Filters.Any(x => x.IsMatch(target)))
{
    // do stuff }
}

但是,如果您想混合使用 All/Any,您可能需要考虑编写自己的扩展方法,将两者结合起来,以避免多次评估输入。 @jonskeet 有一个很好的例子here

尽管如此,通过组合和优化您的正则表达式模式可能会获得最大的收益。手动优化的模式通常是最好的,但您可以尝试使用以下两个 Perl 模块来自动完成:

  • Dan Kogai 的 Regexp-Optimizer-0.23 用于优化/组装模式
use Regexp::Optimizer;
my $o  = Regexp::Optimizer->new->optimize(qr/foobar|fooxar|foozap/);
# $re is now qr/foo(?:[bx]ar|zap)/

仅出于演示目的,将您的示例模式与优化器交替提供:
原始匹配模式:string1|string2 变为优化匹配模式:string[12]

【讨论】:

  • 测试了if (Filters.FirstOrDefault(x =&gt; x.IsMatch(target)) != null),这是一个统计平局。
猜你喜欢
  • 2021-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-17
  • 2013-07-31
  • 2014-02-08
  • 1970-01-01
相关资源
最近更新 更多