c# 正则表达式速度问题

本文关键字:问题 速度 正则表达式 | 更新日期: 2023-09-27 18:35:52

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

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

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

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

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

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

c# 正则表达式速度问题

要理解为什么你的正则表达式很慢,你必须简单地设想正则表达式是如何工作的。

在您的情况下(8000 种替代方案)

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

输入字符串越长,正则表达式的替代项就越多,输入字符串中出现的"几乎但不完全"匹配越多,速度就越慢。

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

探索在字符串中搜索单词的其他方法。哪一个对你有用很大程度上取决于你的输入是什么样子的。

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

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

// produce string[] containing your words
var words = myRegexp.split("''b|''");
var mySet = new HashSet<string>(words);
// usage
mySet.Contains("find this");