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

时间:2008-11-04 16:56:52

标签: c# regex string

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

我有

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

还有其他人吗?

8 个答案:

答案 0 :(得分:7)

正则表达式方法可能是最快的方法,但不是最快的方法。我将一个简单的正则表达式解决方案与下面的手动搜索代码进行了比较,发现对于大型输入字符串,手动搜索代码的速度提高了约2x-2.5x,对于小字符串,速度提高了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-char字符串的结果,中间有一个5位数的字符串,超过10 ^ 6次迭代,每次调用的延迟(以微秒为单位)(较小的数字更快):

简单搜索:0.648396us

Cached Regex:2.1414645us

非缓存正则表达式:3.070116us

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

简单搜索:423.801us

Cached Regex:1155.3948us

非缓存正则表达式:1220.625us

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

答案 1 :(得分:6)

使用正则表达式(\ 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);
}

答案 2 :(得分:2)

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

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

答案 3 :(得分:2)

根本不要使用正则表达式。它比你需要的更强大 - 而且这种力量可能会达到性能。

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

答案 4 :(得分:1)

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

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

将匹配 - asdfkki12345afdkjsdl,12345adfaksk或akdkfa12345

答案 5 :(得分:0)

如果您有一个简单的测试用例如“12345”甚至“12345abcd”,请不要使用正则表达式。他们的速度并不为人所知。

答案 6 :(得分:0)

对于大多数字符串,强力方法比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() ) );

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

答案 7 :(得分:0)

这可能会更快......

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();
        }