我知道如何检查这个.正则表达式,int.parse,tryparse,循环.
谁能告诉我什么是最快的检查方式?
需要的是只需要CHECK就不需要实际解析.
这不是同一个问题:如何识别字符串是否为数字?
问题不仅仅在于识别方式.但是关于什么是最快的方法.
jak*_*sch 244
bool IsDigitsOnly(string str)
{
foreach (char c in str)
{
if (c < '0' || c > '9')
return false;
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
可能是最快的方法.
The*_*ing 60
这是基于相同字符串的1000000个解析的一些基准测试:
更新了release统计信息:
IsDigitsOnly: 384588
TryParse: 639583
Regex: 1329571
Run Code Online (Sandbox Code Playgroud)
这是代码,看起来像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;
}
}
Run Code Online (Sandbox Code Playgroud)
当然值得注意的是,TryParse确实允许前导/尾随空格以及特定于文化的符号.它的字符串长度也受到限制.
Uda*_*day 48
您可以使用LINQ简单地执行此操作
return str.All(char.IsDigit);
.All 对于空字符串返回true,对空字符串返回异常.char.IsDigit 适用于所有Unicode字符.fla*_*ayn 34
char已经有一个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;
}
Run Code Online (Sandbox Code Playgroud)
你可以这样做:
var theString = "839278";
bool digitsOnly = theString.All(char.IsDigit);
Run Code Online (Sandbox Code Playgroud)
Sla*_*lai 21
通过仅使用一次比较char而for不是foreach:而不是:
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;
}
Run Code Online (Sandbox Code Playgroud)
用于测试的代码(总是配置文件,因为结果取决于硬件,版本,订单等):
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;
}
Run Code Online (Sandbox Code Playgroud)
英特尔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
Run Code Online (Sandbox Code Playgroud)
对于任何想要使用较短方法的人,请注意
.All导致true空字符串和异常的null字符串char.IsDigit适用于Nd类别中的所有Unicode字符int.TryParse 还允许白色spase和签名字符Bra*_*vic 13
如果你担心性能,既不使用int.TryParse也不使用Regex- 编写自己的(简单)函数(DigitsOnly或者 DigitsOnly2在下面,但不是 DigitsOnly3 - LINQ似乎会产生很大的开销).
另外,请注意,int.TryParse如果字符串太长而无法"适应" ,则会失败int.
这个简单的基准......
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));
}
}
Run Code Online (Sandbox Code Playgroud)
...产生以下结果......
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
Run Code Online (Sandbox Code Playgroud)
小智 10
我喜欢Linq并且在第一次不匹配时让它退出你可以做到这一点
string str = '0129834X33';
bool isAllDigits = !str.Any( ch=> ch < '0' || ch > '9' );
Run Code Online (Sandbox Code Playgroud)
这应该工作:
Regex.IsMatch("124", "^[0-9]+$", RegexOptions.Compiled)
Run Code Online (Sandbox Code Playgroud)
int.Parse或者int.TryParse不会一直有效,因为字符串可能包含int可以容纳的更多数字.
如果你要多次检查它,那么使用编译的正则表达式是有用的 - 第一次需要更多时间,但之后要快得多.
可能最快的方法是:
myString.All(c => char.IsDigit(c))
Run Code Online (Sandbox Code Playgroud)
注意:如果你的字符串为空,这将返回True,这是不正确的(如果你不认为空为有效数字/数字)
您可以在一行LINQ语句中执行此操作.好吧,我意识到这不一定是最快的,所以从技术上来说不能回答这个问题,但它可能是最容易编写的:
str.All(c => c >= '0' && c <= '9')
Run Code Online (Sandbox Code Playgroud)
这可能会来得超级晚!但我相信它会帮助某人,因为它帮助了我。
private static bool IsDigitsOnly(string str)
{
return str.All(c => c >= '0' && c <= '9');
}
Run Code Online (Sandbox Code Playgroud)
空验证功能:
public static bool IsDigitsOnly(string str)
{
return !string.IsNullOrEmpty(str) && str.All(char.IsDigit);
}
Run Code Online (Sandbox Code Playgroud)
小智 5
如果是单个字符串:
if (str.All(Char.IsDigit))
{
// string contains only digits
}
Run Code Online (Sandbox Code Playgroud)
如果它是一个字符串列表:
if (lstStr.All(s => s.All(Char.IsDigit)))
{
// List of strings contains only digits
}
Run Code Online (Sandbox Code Playgroud)