【问题标题】:what's the quickest way to extract a 5 digit number from a string in c#从c#中的字符串中提取5位数字的最快方法是什么
【发布时间】:2008-11-04 16:56:51
【问题描述】:

在 C# 中从字符串中提取 5 位数字的最快方法是什么。

我有

string.Join(null, System.Text.RegularExpressions.Regex.Split(expression, "[^\\d]"));

还有其他人吗?

【问题讨论】:

  • 取决于字符串的格式!里面还有什么?数字可以出现在任何地方..??

标签: c# regex string


【解决方案1】:

正则表达式方法可能是最快实施但不是最快运行的方法。我将一个简单的正则表达式解决方案与以下手动搜索代码进行了比较,发现手动搜索代码对于大输入字符串的速度提高了 ~2x-2.5 倍,对于小字符串来说速度提高了 4 倍:

static string Search(string expression)
{
  int run = 0;
  for (int i = 0; i < expression.Length; i++)
  {
    char c = expression[i];
    if (Char.IsDigit(c))
      run++;
    else if (run == 5)
      return expression.Substring(i - run, run);
    else
      run = 0;
  }
  return null;
}
const string pattern = @"\d{5}";
static string NotCached(string expression)
{
  return Regex.Match(expression, pattern, RegexOptions.Compiled).Value;
}

static Regex regex = new Regex(pattern, RegexOptions.Compiled);
static string Cached(string expression)
{
  return regex.Match(expression).Value;
}

大约 50 个字符的字符串,中间有一个 5 位数的字符串,超过 10^6 次迭代,每次调用的延迟以微秒为单位(数字越小越快):

简单搜索:0.648396us

缓存的正则表达式:2.1414645us

非缓存正则表达式:3.070116us

在 10^4 次迭代中,中间有一个 5 位字符串的约 40K 字符串的结果,每次调用的延迟以微秒为单位(数字越小越快):

简单搜索:423.801us

缓存的正则表达式:1155.3948us

非缓存正则表达式:1220.625us

有点令人惊讶:我希望 Regex(编译为 IL)与手动搜索相当,至少对于非常大的字符串而言。

【讨论】:

    【解决方案2】:

    使用正则表达式 (\d{5}) 查找字符串中 5 位数字的出现次数,并对匹配项使用 int.Parse 或 decimal.Parse。

    text中只有一个数字的情况。

    int? value = null;
    string pat = @"\d{5}"
    Regex r = new Regex(pat);
    Match m = r.Match(text);
    if (m.Success)
    {
       value = int.Parse(m.Value);
    }
    

    【讨论】:

    • 正如@Jon Skeet 所指出的,如果您提前知道输入的字符,则可能有更快的方法来执行此操作。面对未知的输入格式,这是一种相当快速、稳健的方法。
    【解决方案3】:

    您的意思是将字符串转换为数字吗?还是找到前 5 位字符串,然后将其设为数字​​?无论哪种方式,您都可能会使用 decimal.Parse 或 int.Parse。

    我认为正则表达式是错误的方法。一种更有效的方法是简单地遍历字符串寻找一个数字,然后推进 4 个字符并查看它们是否都是数字。如果是的话,你就有了你的子字符串。它没有那么健壮,不,但它也没有开销。

    【讨论】:

      【解决方案4】:

      根本不要使用正则表达式。它比您需要的强大得多 - 而且这种功能可能会影响性能。

      如果你能提供更多关于你需要它做什么的细节,我们可以编写适当的代码......(测试用例是理想的。)

      【讨论】:

      • 是的。如果您知道输入的字符,则有更好的方法。例如,如果您知道输入中只有一个数字而没有其他数字,那么您可以遍历字符直到找到一个数字,然后开始在接下来的 4 位数字上“累积”该值。
      【解决方案5】:

      如果数字与其他字符存在正则表达式是一个很好的解决方案。

      EG:([0-9]{5})

      将匹配 - asdfkki12345afdkjsdl、12345adfaksk 或 akdkfa12345

      【讨论】:

        【解决方案6】:

        如果您有像“12345”甚至“12345abcd”这样的简单测试用例,则根本不要使用正则表达式。他们不以速度着称。

        【讨论】:

          【解决方案7】:

          对于大多数字符串,蛮力方法比 RegEx 更快。

          一个相当不错的例子是:

          string strIWantNumFrom = "qweqwe23qeeq3eqqew9qwer0q";
          
          int num = int.Parse(
              string.Join( null, (
                  from c in strIWantNumFrom.ToCharArray()
                  where c == '1' || c == '2' || c == '3' || c == '4' || c == '5' ||
                      c == '6' || c == '7' || c == '8' || c == '9' || c == '0'
                  select c.ToString()
              ).ToArray() ) );
          

          毫无疑问,有很多更快的方法,以及许多取决于字符串的确切格式的优化。

          【讨论】:

            【解决方案8】:

            这可能会更快...

            public static string DigitsOnly(string inVal)
                    {
                        char[] newPhon = new char[inVal.Length];
                        int i = 0;
                        foreach (char c in inVal)
                            if (c.CompareTo('0') > 0 && c.CompareTo('9') < 0)
                                newPhon[i++] = c;
                        return newPhon.ToString();
                    }
            

            如果你想把它限制在最多五位数,那么

            public static string DigitsOnly(string inVal)
                    {
                        char[] newPhon = new char[inVal.Length];
                        int i = 0;
                        foreach (char c in inVal)
                            if (c.CompareTo('0') > 0 && c.CompareTo('9') < 0 && i < 5)
                                newPhon[i++] = c;
                        return newPhon.ToString();
                    }
            

            【讨论】:

              猜你喜欢
              • 2017-04-10
              • 1970-01-01
              • 2017-05-19
              • 2020-04-07
              • 1970-01-01
              • 2021-11-16
              • 2010-09-06
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多