c#正则表达式速度问题

c# Regular Expression speed issue

我在 C# 中有一个正则表达式,其中的模式是 8000 多个单词(或单词组),每个单词由单词边界分隔,即:

"\bword1\b|\bword2 word3 word4\b|.......etc"

我正在尝试将字符串中的一个词(或一组词)与该表达式中的任何一个词(或一组词)相匹配。一切正常,除了我发现平均需要 37 毫秒才能完成操作。

有趣的是,如果我做同样的事情但使用 String.IndexOf 和一些复杂的方法,它确实运行得更快(但仍然太慢),我觉得这很奇怪。

我特别了解其他正则表达式引擎 re2/google,但我真的很想尽可能使用 C# 内置功能。

如果有人有建议,我们将不胜感激。

要了解正则表达式运行缓慢的原因,您必须简单地想象一下正则表达式的工作原理。

你的情况(8000 个备选方案)

  • 第 1 步。从输入字符 0 开始。
  • 第 2 步。尝试匹配备选方案 0。糟糕,没有匹配。
  • 第 3 步。尝试匹配备选方案 1。糟糕,没有匹配。
  • ...
  • 第 4000 步。尝试匹配备选 4001。耶!第一个字符匹配!
  • 第 4001 步。尝试匹配备选 4001。耶!第二个字符匹配!
  • 步骤 4002。尝试匹配备选 4001。糟糕,没有匹配。
  • 步骤 4003。尝试匹配备选 4002。糟糕,没有匹配。
  • ...
  • 第 8963 步。尝试匹配备选 7999。糟糕,没有匹配。
  • 步骤 8964。输入字符 0 处的所有备选方案均失败。
  • 第8965步。移动到输入字符1。
  • 第 8966 步。尝试匹配替代项 0。糟糕,没有匹配。
  • ...

输入字符串越长,正则表达式的替代项越多,输入字符串中出现的 "almost, but not quite" 匹配项越多,速度就越慢。

如果 String.IndexOf() 可以让它更快,那就去做吧。你永远不会用正则表达式让它变得更快。

探索在字符串中搜索单词的其他方法。哪一个适合您在很大程度上取决于您输入的内容。

我建议切换到 HashSet,因为它似乎更适合您的任务。

这是您可以执行的操作的草稿:

// produce string[] containing your words
var words = myRegexp.split("\b|\");

var mySet = new HashSet<string>(words);
// usage
mySet.Contains("find this");