查找具有正则表达式的字符的第n个出现的性能问题

Ste*_*eve 0 .net c# regex

我有一个正则表达式来查找nth字符串中出现的字符,这里是代码:

 public static int NthIndexOf(this string target, string value, int n)
    {
        Match m = Regex.Match(target, "((" + value + ").*?){" + n + "}");

        if (m.Success)
        {
            return m.Groups[2].Captures[n - 1].Index;
        }
        else
        {
             return -1;
        }
    }
Run Code Online (Sandbox Code Playgroud)

现在,我在这个字符串中有1594个条目,有1593个分号.如果我写:

tempstring.NthIndexOf(";", 1593) 
Run Code Online (Sandbox Code Playgroud)

答案立即正确回复.如果我给它任何超过1594的东西它会挂起.有谁知道如何解决这一问题?

测试用例

 string holder = "test;test2;test3";
        string test = "";
        for (int i = 0; i < 600; i++)
        {
            test += holder;
        }
        int index = test.NthIndexOf(";", 2000);
Run Code Online (Sandbox Code Playgroud)

这需要很长时间.将600更改为6,速度非常快.使2000至1700,它也非常快.

为什么我的正则表达式如此之慢?

Dan*_*ant 9

如果你真的只是寻找字符重复,而不是字符串重复,那么你应该能够用简单的东西替换你的方法

public static int NthIndexOf(this string target, char testChar, int n)
{
   int count = 0;

   for(int i=0; i<target.Length; i++)
   {
      if(target[i] == testChar)
      {
         count++;
         if(count == n) return i;  
      }
   }

   return -1;
}
Run Code Online (Sandbox Code Playgroud)

并使用它.它的限制应该少得多.

至于为什么你的原始正则表达式变慢,这是我怀疑的:

  • 对于你的快速情况,它是有效的,因为它可以找到匹配它的第一次通过(每个组只匹配一个字符)
  • 对于慢的情况是因为它找不到匹配(并且永远找不到匹配,因为没有足够的分号来满足正则表达式),但它递归尝试每种可能的方式来分解字符串(这是一个非常大的操作)