c#正则表达式速度问题

时间:2015-01-02 17:36:22

标签: c# regex

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

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

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

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

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

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

2 个答案:

答案 0 :(得分:4)

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

在你的情况下(8000个替代品)

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

输入字符串越长,正则表达式的替代品就越多,“差不多”,“但不完全”#34;匹配发生在输入字符串中,这将得到的速度越慢。

如果您可以使用String.IndexOf()加快速度,请执行此操作。使用正则表达式永远不会让它更快。

探索搜索字符串的其他方法。哪一个适合你,很大程度上取决于你的输入是什么样的。

答案 1 :(得分:0)

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

以下是您可以做的草稿:

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

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