判断某个字符串是否为数字
判斷某個字符串是否為數字,各個語言實現方法里不盡相同。
在VBS中,IsNumeric()函數的實際作用是判斷參數表達式是否是數值,而這個所謂的“數值”不僅僅包含普通的數字,還包括(但可能不限于)如下情況:
科學計數法表達式,如“2e7”和“2d7”;
十六進制數,如“&H0A”;
八進制數,如“&6”;
當前區域下設置的貨幣金額表達式,如“¥12.44”;
加圓括號的數字,如“(34)”;
顯式指定正負的數字,如“+2.1”和“-2.1”;
含有逗號的數字字符串,如“12,25”。
不僅僅是VBS,JScript/JavaScript的isNaN()也存在類似問題,T-SQL中的IsNumeric()同樣如此!大家可以自行研究。
參考了http://www.tongyi.net/develop/cshap/1040479.html?文章,直接把內容復制過來。
在編程的時候,經常遇到要判斷一個字符串中的字符是否全部是數字(0-9),本來是一個很容易實現的功能,但程序員首先會想到的是,這樣簡單的功能有沒有現成的函數可以用呢?VB.NET中有個IsNumeric(object),C#中只有判斷單個字符的Char.IsNumber(),IsNumeric可以判斷double類型的數字字符串,但無法排除正負號和小數點,如果判斷字符串是否是一個數的話用它挺合適,但不能用來判斷字符串是否全部由數字組成的。沒現成的方法了,只好自己寫函數:
public static bool IsNum(String str)
{
??? for(int i=0;i<str.Length;i++)
??? {
??????? if(!Char.IsNumber(str,i))
??????? return false;
??? }
??? return true;
}
或用正則表達式:"^/d+$"
還可以用Int32.Parse()拋出的Exception來判斷:
try
{
??? Int32.Parse(toBeTested);
}
catch
{
??? //發生了異常,那么就不是數字了。
}
那么哪一種方法最好呢?各有優劣。我順手寫了一個程序對每一種方法所需要的時間進行了測試。測試程序Main()內容如下:
Regex isNumeric = new Regex(@"^/d+$");
int times = 10000000;
int start, end;
int i;
string toBeTested = "6741s";
#region Test user function
start = System.Environment.TickCount;
for(i=0; i<times; i++)
{
?TimingTest.IsNum(toBeTested);
}
end = System.Environment.TickCount;
Console.WriteLine("User function Time: " + (end-start)/1000.0 + " Seconds");
#endregion
#region Test Regular Expression
start = System.Environment.TickCount;
for(i=0; i<times; i++)
{
?isNumeric.IsMatch(toBeTested);
}
end = System.Environment.TickCount;
Console.WriteLine("Regular Expression Time: " + (end-start)/1000.0 + " Seconds");
#endregion
#region Test Exception
start = System.Environment.TickCount;
for(i=0; i<times/100; i++)
{
?try
?{
??Int32.Parse(toBeTested);
?}
?catch
?{
??//發生了異常,那么就不是數字了。
?}
}
end = System.Environment.TickCount;
Console.WriteLine("Exception Time: " + (end-start)/10.0 + " Seconds");
#endregion
#region Test VB.NET IsNumeric()
start = System.Environment.TickCount;
for(i=0; i<times/10; i++)
{
?Microsoft.VisualBasic.Information.IsNumeric(toBeTested);
}
end = System.Environment.TickCount;
Console.WriteLine("VB.NET IsNumeric() Time: " + (end-start)/100.0 + " Seconds");
#endregion
??? 因為Exception所用的時間太長,所以只測試了1/100,這樣不太嚴謹,但是數量級不會錯的。
三次運行的結果是:
User function Time:?1.938 Seconds
Regular Expression Time: 11.921 Seconds
Exception Time: 600 Seconds
VB.NET IsNumeric() Time: 40.797 Seconds
User function Time:?1.953 Seconds
Regular Expression Time: 12.016 Seconds
Exception Time: 590.6 Seconds
VB.NET IsNumeric() Time: 40 Seconds
User function Time:?2.000 Seconds
Regular Expression Time: 12 Seconds
Exception Time: 595.3 Seconds
VB.NET IsNumeric() Time: 39.69 Seconds
平均時間:
1.964
11.979
595.3
40.162
速度之比依次約為:303 : 49.7 : 1 : 14.82
結果很明顯,自定義函數速度最快,異常的速度最慢。假如不需要拋異常的話string toBeTested = "67412";結果就成了:
User function Time: 1.922 Seconds
Regular Expression Time: 9.64 Seconds
Exception Time: 3.1 Seconds
VB.NET IsNumeric() Time: 39.07 Seconds
速度之比依次約為:20.33 : 4.05 : 12.60?: 1
結論:
??? 自定義函數可以獲得最大的靈活性和最高的性能,而且復雜性也不高,是最佳的方法。
??? 正則表達式法和IsNumeric速度在同一個數量級上,但正則表達式可以確定一種字符串的格式,比如規定一定要有或沒有小數點等,而IsNumeric無法做到。
??? 使用異常是應該避免的。建議僅把Exception作為處理異常的一種手段,而不是作為控制流程的一種手段。測試也表明,當有異常拋出時,要消耗大量的資源。
??? IsNumeric是現成的函數,用起來最省事,只能判斷所給的參數是否是數值(boolean/byte/int16/int32/int64/single/double/decimal),無法作進一步的要求(是否有小數點等)。但IsNumeric的參數是object,不局限于string。
??? 寫到這里,我不禁想,還有沒有比自定義函數更快的方法呢?答案是肯定的。在前面的自定義函數中,用的是Char.IsNumber()函數,這個函數不僅能判斷標準ASCII碼中的''''1'''',甚至對全角中文的''''1''''的判斷也是true,可見Char.IsNumber()判斷的是所有的Unicode字符中的數字,其他語言中的數字也包括了。假如我們只允許ASCII中的''''1''''的話,我們可以這樣改:
public static bool IsNum(String str)
{
?for(int i=0;i<str.Length;i++)
?{
??if(str[i]<=''''0'''' || str[i]>=''''9'''')
???return false;
?}
?return true;
}
??? 測試結果也令我吃驚,這樣比原來的IsNum速度提高了近10倍,平均執行時間是0.205秒!
??? 結果全部出來了,該怎樣選擇大家心里肯定已經有數了,我也不需要再說什么了。
總結
以上是生活随笔為你收集整理的判断某个字符串是否为数字的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 元宇宙爆火,虚拟人的商业落地现实又残酷
- 下一篇: nginx 简单配置