我知道一些方法来检查字符串是否只包含数字: 正则表达式,int。解析,tryparse,循环等等。
谁能告诉我最快的方法是什么?
我只需要检查值,不需要实际解析它。
通过“数字”,我是指具体的ASCII数字:0 1 2 3 4 5 6 7 8 9。
如果字符串是数字,这个问题与Identify不同,因为这个问题不仅是关于如何识别,而且是关于识别的最快方法是什么。
我知道一些方法来检查字符串是否只包含数字: 正则表达式,int。解析,tryparse,循环等等。
谁能告诉我最快的方法是什么?
我只需要检查值,不需要实际解析它。
通过“数字”,我是指具体的ASCII数字:0 1 2 3 4 5 6 7 8 9。
如果字符串是数字,这个问题与Identify不同,因为这个问题不仅是关于如何识别,而且是关于识别的最快方法是什么。
当前回答
我喜欢Linq,让它在第一次不匹配时退出,你可以这样做
string str = '0129834X33';
bool isAllDigits = !str.Any( ch=> ch < '0' || ch > '9' );
其他回答
如果你关心性能,不要使用int型。TryParse或Regex -编写自己的(简单的)函数(下面是DigitsOnly或DigitsOnly2,但不是DigitsOnly3 - LINQ似乎会引起很大的开销)。
另外,要注意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
下面是一些基于相同字符串的1000000次解析的基准测试:
更新发布数据:
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确实允许前导/尾随空白以及区域性特定的符号。弦的长度也有限制。
我做了一些小改变@ theecodeking的回答。
似乎;
对于int类型,最快的方法是TryParse
对于长类型最快的方法是正则表达式。
我的结果如下(打勾)
For int:
TryParse Max: 355788
IsDigitsOnly Max: 787013
Regex Max: 1297691
TryParse Avg: 186007
IsDigitsOnly Avg: 430963
Regex Avg: 464657,79
TryParse Min: 162742
IsDigitsOnly Min: 335646
Regex Min: 452121
For float :
TryParse Max : 3151995
IsDigitsOnly Max: 1392740
Regex Max : 1283451
TryParse Avg: 1391636
IsDigitsOnly Avg: 824029
Regex Avg: 501176
TryParse Min: 1187410
IsDigitsOnly Min: 706646
Regex Min: 476204
代码为long:
using System.Diagnostics;
using System.Text.RegularExpressions;
class Program
{
private static Regex regex = new Regex("^[0-9]+$", RegexOptions.Compiled);
static void Main(string[] args)
{
Stopwatch watch = new Stopwatch();
watch.Start();
watch.Stop();
watch.Reset();
List<TimeSpan> tryparse = new List<TimeSpan>();
List<TimeSpan> isdigitsonly = new List<TimeSpan>();
List<TimeSpan> regexss = new List<TimeSpan>();
for (int say = 0; say < 1000; say++)
{
float value;
string test = Random.Shared.NextInt64(1000,long.MaxValue).ToString();
watch.Start();
for (int i = 0; i < 1000000; i++)
{
float.TryParse(test, out value);
}
watch.Stop();
//Console.WriteLine("TryParse: " + watch.Elapsed);
tryparse.Add(watch.Elapsed);
watch.Reset();
watch.Start();
for (int i = 0; i < 1000000; i++)
{
IsDigitsOnly(test);
}
watch.Stop();
//Console.WriteLine("IsDigitsOnly: " + watch.Elapsed);
isdigitsonly.Add(watch.Elapsed);
watch.Reset();
watch.Start();
for (int i = 0; i < 1000000; i++)
{
regex.IsMatch(test);
}
watch.Stop();
regexss.Add(watch.Elapsed);
watch.Reset();
// Console.WriteLine("Regex: " + watch.Elapsed);
Console.Write("---------------------% " + (Convert.ToDecimal( say)/ 999 * 100).ToString("N2") + "---------------------------");
Console.CursorLeft = 0;
}
Console.WriteLine();
Console.WriteLine($"TryParse: {tryparse.Max(t => t.Ticks)}");
Console.WriteLine($"IsDigitsOnly: {isdigitsonly.Max(t => t.Ticks)}");
Console.WriteLine($"Regex: {regexss.Max(t => t.Ticks)}");
Console.WriteLine();
Console.WriteLine($"TryParse Avg: {tryparse.Average(t => t.Ticks)}");
Console.WriteLine($"IsDigitsOnly Avg: {isdigitsonly.Average(t => t.Ticks)}");
Console.WriteLine($"Regex Avg: {regexss.Average(t => t.Ticks)}");
Console.WriteLine();
Console.WriteLine($"TryParse Min: {tryparse.Min(t => t.Ticks)}");
Console.WriteLine($"IsDigitsOnly Min: {isdigitsonly.Min(t => t.Ticks)}");
Console.WriteLine($"Regex Min: {regexss.Min(t => t.Ticks)}");
Console.ReadLine();
}
static bool IsDigitsOnly(string str)
{
foreach (char c in str)
{
if (c < '0' || c > '9')
return false;
}
return true;
}
}
另一种方法!
string str = "12345";
bool containsOnlyDigits = true;
try { if(Convert.ToInt32(str) < 0){ containsOnlyDigits = false; } }
catch { containsOnlyDigits = false; }
在这里,如果Convert.ToInt32(str)语句失败,则字符串不仅仅包含数字。另一种可能性是,如果字符串具有“-12345”,并成功转换为-12345,则会检查转换后的数字是否小于零。
该字符已经有一个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);