最快的方法来检查string是否只包含数字

我知道一些如何检查这个问题的方法。 正则expression式, int.parsetryparse ,循环。

谁能告诉我什么是最快的方法来检查?

需要的只是CHECK ,实际上不需要parsing。

这不是一个问题: 我如何确定一个string是否是一个数字?

问题不仅在于如何识别。 但是关于什么是最快的方法。

 bool IsDigitsOnly(string str) { foreach (char c in str) { if (c < '0' || c > '9') return false; } return true; } 

可能是最快的方法来做到这一点。

以下是基于相同string的1000000个分析的一些基准:

release统计信息更新:

 IsDigitsOnly: 384588 TryParse: 639583 Regex: 1329571 

这是代码,看起来像IsDigitsOnly更快:

 class Program { private static Regex regex = new Regex("^[0-9]+$", RegexOptions.Compiled); static void Main(string[] args) { Stopwatch watch = new Stopwatch(); string test = int.MaxValue.ToString(); int value; watch.Start(); for(int i=0; i< 1000000; i++) { int.TryParse(test, out value); } watch.Stop(); Console.WriteLine("TryParse: "+watch.ElapsedTicks); watch.Reset(); watch.Start(); for (int i = 0; i < 1000000; i++) { IsDigitsOnly(test); } watch.Stop(); Console.WriteLine("IsDigitsOnly: " + watch.ElapsedTicks); watch.Reset(); watch.Start(); for (int i = 0; i < 1000000; i++) { regex.IsMatch(test); } watch.Stop(); Console.WriteLine("Regex: " + watch.ElapsedTicks); Console.ReadLine(); } static bool IsDigitsOnly(string str) { foreach (char c in str) { if (c < '0' || c > '9') return false; } return true; } } 

当然,值得注意的是,TryParse确实允许前/后空白以及培养特定的符号。 这也是有限的string的长度。

字符已经有一个IsDigit(char c)这样做:

  public static bool IsDigit(char c) { if (!char.IsLatin1(c)) return CharUnicodeInfo.GetUnicodeCategory(c) == UnicodeCategory.DecimalDigitNumber; if ((int) c >= 48) return (int) c <= 57; else return false; } 

你可以简单地做到这一点:

 var theString = "839278"; bool digitsOnly = theString.All(char.IsDigit); 

你可以简单地使用LINQ来做到这一点

return str.All(char.IsDigit);

如果你关心性能,不要使用int.TryParseint.TryParse编写你自己的(简单的)函数(下面的DigitsOnlyDigitsOnly2 ,而不是 DigitsOnly3 – LINQ似乎会产生很大的开销)。

另外,请注意,如果string太长而不能“适合” int ,则int.TryParse将会失败。

这个简单的基准…

 class Program { static bool DigitsOnly(string s) { int len = s.Length; for (int i = 0; i < len; ++i) { char c = s[i]; if (c < '0' || c > '9') return false; } return true; } static bool DigitsOnly2(string s) { foreach (char c in s) { if (c < '0' || c > '9') return false; } return true; } static bool DigitsOnly3(string s) { return s.All(c => c >= '0' && c <= '9'); } static void Main(string[] args) { const string s1 = "916734184"; const string s2 = "916734a84"; const int iterations = 1000000; var sw = new Stopwatch(); sw.Restart(); for (int i = 0 ; i < iterations; ++i) { bool success = DigitsOnly(s1); bool failure = DigitsOnly(s2); } sw.Stop(); Console.WriteLine(string.Format("DigitsOnly: {0}", sw.Elapsed)); sw.Restart(); for (int i = 0; i < iterations; ++i) { bool success = DigitsOnly2(s1); bool failure = DigitsOnly2(s2); } sw.Stop(); Console.WriteLine(string.Format("DigitsOnly2: {0}", sw.Elapsed)); sw.Restart(); for (int i = 0; i < iterations; ++i) { bool success = DigitsOnly3(s1); bool failure = DigitsOnly3(s2); } sw.Stop(); Console.WriteLine(string.Format("DigitsOnly3: {0}", sw.Elapsed)); sw.Restart(); for (int i = 0; i < iterations; ++i) { int dummy; bool success = int.TryParse(s1, out dummy); bool failure = int.TryParse(s2, out dummy); } sw.Stop(); Console.WriteLine(string.Format("int.TryParse: {0}", sw.Elapsed)); sw.Restart(); var regex = new Regex("^[0-9]+$", RegexOptions.Compiled); for (int i = 0; i < iterations; ++i) { bool success = regex.IsMatch(s1); bool failure = regex.IsMatch(s2); } sw.Stop(); Console.WriteLine(string.Format("Regex.IsMatch: {0}", sw.Elapsed)); } } 

…产生以下结果…

 DigitsOnly: 00:00:00.0346094 DigitsOnly2: 00:00:00.0365220 DigitsOnly3: 00:00:00.2669425 int.TryParse: 00:00:00.3405548 Regex.IsMatch: 00:00:00.7017648 

我喜欢Linq,并在第一次不匹配时退出,你可以这样做

 string str = '0129834X33'; bool isAllDigits = !str.Any( ch=> ch < '0' || ch > '9' ); 

通过使用每个char而不是每个char比较,可以快20%左右:

 bool isDigits(string s) { if (s == null || s == "") return false; for (int i = 0; i < s.Length; i++) if ((s[i] ^ '0') > 9) return false; return true; } 

用于testing的代码(因为结果取决于硬件,版本,顺序等,因此始终是configuration文件):

 static bool isDigitsFr(string s) { if (s == null || s == "") return false; for (int i = 0; i < s.Length; i++) if (s[i] < '0' || s[i] > '9') return false; return true; } static bool isDigitsFu(string s) { if (s == null || s == "") return false; for (int i = 0; i < s.Length; i++) if ((uint)(s[i] - '0') > 9) return false; return true; } static bool isDigitsFx(string s) { if (s == null || s == "") return false; for (int i = 0; i < s.Length; i++) if ((s[i] ^ '0') > 9) return false; return true; } static bool isDigitsEr(string s) { if (s == null || s == "") return false; foreach (char c in s) if (c < '0' || c > '9') return false; return true; } static bool isDigitsEu(string s) { if (s == null || s == "") return false; foreach (char c in s) if ((uint)(c - '0') > 9) return false; return true; } static bool isDigitsEx(string s) { if (s == null || s == "") return false; foreach (char c in s) if ((c ^ '0') > 9) return false; return true; } static void test() { var w = new Stopwatch(); bool b; var s = int.MaxValue + ""; int r = 12345678*2; var ss = new SortedSet<string>(); //s = string.Concat(Enumerable.Range(0, 127).Select(i => ((char)i ^ '0') < 10 ? 1 : 0)); w.Restart(); for (int i = 0; i < r; i++) b = s.All(char.IsDigit); w.Stop(); ss.Add(w.Elapsed + ".All .IsDigit"); w.Restart(); for (int i = 0; i < r; i++) b = s.All(c => c >= '0' && c <= '9'); w.Stop(); ss.Add(w.Elapsed + ".All <>"); w.Restart(); for (int i = 0; i < r; i++) b = s.All(c => (c ^ '0') < 10); w.Stop(); ss.Add(w.Elapsed + " .All ^"); w.Restart(); for (int i = 0; i < r; i++) b = isDigitsFr(s); w.Stop(); ss.Add(w.Elapsed + " for <>"); w.Restart(); for (int i = 0; i < r; i++) b = isDigitsFu(s); w.Stop(); ss.Add(w.Elapsed + " for -"); w.Restart(); for (int i = 0; i < r; i++) b = isDigitsFx(s); w.Stop(); ss.Add(w.Elapsed + " for ^"); w.Restart(); for (int i = 0; i < r; i++) b = isDigitsEr(s); w.Stop(); ss.Add(w.Elapsed + " foreach <>"); w.Restart(); for (int i = 0; i < r; i++) b = isDigitsEu(s); w.Stop(); ss.Add(w.Elapsed + " foreach -"); w.Restart(); for (int i = 0; i < r; i++) b = isDigitsEx(s); w.Stop(); ss.Add(w.Elapsed + " foreach ^"); MessageBox.Show(string.Join("\n", ss)); return; } 

英特尔i5-3470 @ 3.2GHz,VS 2015 .NET 4.6.1上的结果已启用发行模式和优化:

 time method ratio 0.7776 for ^ 1.0000 0.7984 foreach - 1.0268 0.8066 foreach ^ 1.0372 0.8940 for - 1.1497 0.8976 for <> 1.1543 0.9456 foreach <> 1.2160 4.4559 .All <> 5.7303 4.7791 .All ^ 6.1458 4.8539 .All. IsDigit 6.2421 

对于试图使用较短方法的人,请注意

  • .All结果true空的string和空string的exception
  • char.IsDigit适用于Nd类别中的所有Unicode字符
  • int.TryParse也允许白色的spase和符号字符

这应该工作:

 Regex.IsMatch("124", "^[0-9]+$", RegexOptions.Compiled) 

int.Parseint.TryParse不会总是工作,因为string可能包含更多的数字,一个int可以容纳。

如果你打算这样做,不止一次检查使用编译正则expression式是有用的 – 第一次需要更多的时间,但是之后会更快。

你可以在一行LINQ语句中做到这一点。 好的,我意识到这不一定是最快的,所以在技术上没有回答这个问题,但这可能是最简单的写法:

 str.All(c => c >= '0' && c <= '9') 

可能最快的方法是:

 myString.All(c => char.IsDigit(c)) 

注意:如果你的string是空的,那么它将返回True ,这是不正确的(如果你不认为空有效的数字/数字)

您可以尝试使用正则expression式通过使用C#中的.IsMatch(string input, string pattern)方法testinginputstring以仅具有数字(0-9)。

 using System; using System.Text.RegularExpression; public namespace MyNS { public class MyClass { public void static Main(string[] args) { string input = Console.ReadLine(); bool containsNumber = ContainsOnlyDigits(input); } private bool ContainOnlyDigits (string input) { bool containsNumbers = true; if (!Regex.IsMatch(input, @"/d")) { containsNumbers = false; } return containsNumbers; } } } 

问候

这将完美的工作,还有很多其他的方法,但这将工作

 bool IsDigitsOnly(string str) { if (str.Length > 0)//if contains characters { foreach (char c in str)//assign character to c { if (c < '0' || c > '9')//check if its outside digit range return false; } }else//empty string { return false;//empty string } return true;//only digits } 

非常聪明和简单的方法来检测你的string是否只包含数字是这样:

 string s = "12fg"; if(s.All(char.IsDigit)) { return true; // contains only digits } else { return false; // contains not only digits } 

试试这个代码:

 bool isDigitsOnly(string str) { try { int number = Convert.ToInt32(str); return true; } catch (Exception) { return false; } } 
 public bool CheckforDigits(string x) { int tr; return x.All(r=> int.TryParse(r.ToString(), out tr)); } 

怎么样char.IsDigit(myChar)