好吧所以我有一长串数字,但我需要确保它没有任何数字,最简单的方法是什么?
答案 0 :(得分:3)
您可以使用char.IsDigit
:
var containsOnlyDigits = "007".All(char.IsDigit); // true
答案 1 :(得分:3)
扫描字符串,测试字符... s.All(c => Char.IsDigit(c))
Enumerable.All会在找到非数字字符后立即退出。 IsDigit检查char很快。成本是O(N)(尽可能好);当然,它比尝试解析字符串(如果字符串真的很长会失败)或使用regexpr ...更好。
如果您尝试使用此解决方案,并且看到它对您来说太慢,您可以随时返回到旧的循环来扫描字符串..
foreach (char c in s) {
if (!Char.IsDigit(c))
return false;
}
return true;
甚至更好:
for (int i = 0; i < s.Length; i++){
if (!Char.IsDigit(s[i]))
return false;
}
return true;
编辑:基准,最后!
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text.RegularExpressions;
namespace FindTest
{
class Program
{
const int Iterations = 1000;
static string TestData;
static Regex regex;
static bool ValidResult = false;
static void Test(Func<string, bool> function)
{
Console.Write("{0}... ", function.Method.Name);
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < Iterations; i++)
{
bool result = function(TestData);
if (result != ValidResult)
{
throw new Exception("Bad result: " + result);
}
}
sw.Stop();
Console.WriteLine(" {0}ms", sw.ElapsedMilliseconds);
GC.Collect();
}
static void InitializeTestDataEnd(int length)
{
TestData = new string(Enumerable.Repeat('1', length - 1).ToArray()) + "A";
}
static void InitializeTestDataStart(int length)
{
TestData = "A" + new string(Enumerable.Repeat('1', length - 1).ToArray());
}
static void InitializeTestDataMid(int length)
{
TestData = new string(Enumerable.Repeat('1', length / 2).ToArray()) + "A" + new string(Enumerable.Repeat('1', length / 2 - 1).ToArray());
}
static void InitializeTestDataPositive(int length)
{
TestData = new string(Enumerable.Repeat('1', length).ToArray());
}
static bool LinqScan(string s)
{
return s.All(Char.IsDigit);
}
static bool ForeachScan(string s)
{
foreach (char c in s)
{
if (!Char.IsDigit(c))
return false;
}
return true;
}
static bool ForScan(string s)
{
for (int i = 0; i < s.Length; i++)
{
if (!Char.IsDigit(s[i]))
return false;
}
return true;
}
static bool Regexp(string s)
{
// String contains numbers
return regex.IsMatch(s);
// String contains letters
//return Regex.IsMatch(s, "\\w", RegexOptions.Compiled);
}
static void Main(string[] args)
{
regex = new Regex(@"^\d+$", RegexOptions.Compiled);
Console.WriteLine("Positive (all digitis)");
InitializeTestDataPositive(100000);
ValidResult = true;
Test(LinqScan);
Test(ForeachScan);
Test(ForScan);
Test(Regexp);
Console.WriteLine("Negative (char at beginning)");
InitializeTestDataStart(100000);
ValidResult = false;
Test(LinqScan);
Test(ForeachScan);
Test(ForScan);
Test(Regexp);
Console.WriteLine("Negative (char at end)");
InitializeTestDataEnd(100000);
ValidResult = false;
Test(LinqScan);
Test(ForeachScan);
Test(ForScan);
Test(Regexp);
Console.WriteLine("Negative (char in middle)");
InitializeTestDataMid(100000);
ValidResult = false;
Test(LinqScan);
Test(ForeachScan);
Test(ForScan);
Test(Regexp);
Console.WriteLine("Done");
}
}
}
我测试了阳性和三个阴性,1)测试哪个正则表达式是正确的,2)寻找我怀疑的确认...
我的意见是Regexp.IsMatch
也必须扫描字符串,所以它似乎是:
时间与扫描一致,只差3倍:
Positive (all digitis)
LinqScan... 952ms
ForeachScan... 1043ms
ForScan... 869ms
Regexp... 3074ms
Negative (char at beginning)
LinqScan... 0ms
ForeachScan... 0ms
ForScan... 0ms
Regexp... 0ms
Negative (char at end)
LinqScan... 921ms
ForeachScan... 958ms
ForScan... 867ms
Regexp... 3986ms
Negative (char in middle)
LinqScan... 455ms
ForeachScan... 476ms
ForScan... 430ms
Regexp... 1982ms
致谢:我借用了Jon Skeet的测试功能
结论:s.All(Char.IsDigit)
是有效的,而且非常简单(毕竟这是最初的问题)。就个人而言,我发现它比正则表达式更容易(因为我不熟悉C#regexp语法 - 我不熟悉C#regexp语法 - 这是标准的,但我不知道 - 并且建议的解决方案是错误的) 。
所以..测量,并且不相信像“LINQ很慢”或“RegExp很慢”的神话。
毕竟,他们都可以完成任务(这实际上取决于你需要它),选择你喜欢的那个。
答案 2 :(得分:0)
使用正则表达式:
using System.Text.RegularExpressions;
string myString = "some long characters...";
if(Regex.IsMatch(myString, @"^\d+$", RegexOptions.Compiled))
{
// String contains only numbers
}
if(Regex.IsMatch(myString, @"^\w+$", RegexOptions.Compiled))
{
// String contains only letters
}
答案 3 :(得分:0)
尝试使用TryParse
bool longStringisInt = Int64.TryParse(longString, out number);
如果字符串(即longString)无法转换为int(即包含字母),则bool为false,否则为真。
编辑:更改为Int64以确保更广泛的覆盖率
答案 4 :(得分:0)
您可以使用IndexOfAny
bool containsDigits = mystring.IndexOfAny("0123456789".ToCharArray()) != -1;
在Linq,你必须这样做:
bool containsDigits = mystring.Any(char.IsDigit);
编辑:
我计时了,事实证明Linq解决方案慢。
对于字符串长度1,000,000,linq解决方案的执行时间约为13毫秒,IndexOfAny
的执行时间为1毫秒。
对于字符串长度10,000,000,Linq的执行时间仍然是~122ms,而IndexOfAny
是~18ms。