Java中判斷字符串是否為數字


轉載:https://blog.csdn.net/u013066244/article/details/53197756 

用JAVA自帶的函數
public static boolean isNumericZidai(String str) {
for (int i = 0; i < str.length(); i++) {
System.out.println(str.charAt(i));
if (!Character.isDigit(str.charAt(i))) {
return false;
}
}
return true;
}

其中Character.isDigit方法:確定或判斷指定字符是否是一個數字。

測試方法:

public static void main(String[] args) {
double aa = -19162431.1254;
String a = "-19162431.1254";
String b = "-19162431a1254";
String c = "中文";
System.out.println(isNumericzidai(Double.toString(aa)));
System.out.println(isNumericzidai(a));
System.out.println(isNumericzidai(b));
System.out.println(isNumericzidai(c));
}

結果顯示:

false
false
false
false

這種方法顯然不能判斷 負數。

用正則表達式
public static boolean isNumericzidai(String str) {
Pattern pattern = Pattern.compile("-?[0-9]+.?[0-9]+");
Matcher isNum = pattern.matcher(str);
if (!isNum.matches()) {
return false;
}
return true;
}

網上給出的最好的方法,可惜還是錯誤;首先正則表達式-?[0-9]+.?[0-9]+這里就錯誤
網上說:可匹配所有數字。
比如:

double aa = -19162431.1254;
String a = "-19162431.1254";
String b = "-19162431a1254";
String c = "中文";
System.out.println(isNumericzidai(Double.toString(aa)));
System.out.println(isNumericzidai(a));
System.out.println(isNumericzidai(b));
System.out.println(isNumericzidai(c));

結果

false
true
true
false

正確的正則表達式是:-?[0-9]+\\.?[0-9]*,點號.,是匹配任意字符,需要進行轉義。

注意:感謝網友留言提示了一個錯誤,之前我的正則表達式是這么寫的:
-?[0-9]+\\.?[0-9]+,這種正則表達式在匹配0-9的正負數時,會出錯,這是因為該表達式最后是+,表示的是匹配前一個字符1次或無限次。
也就是說在匹配一位的時候,會出現錯誤。所以改為*,表示匹配前一位字符0次或無限次。

System.out.println(isNumeric("9"));


結果為

true

於是我們改成:

public static boolean isNumericzidai(String str) {
Pattern pattern = Pattern.compile("-?[0-9]+\\.?[0-9]*");
Matcher isNum = pattern.matcher(str);
if (!isNum.matches()) {
return false;
}
return true;
}

執行上面代碼結果:

false
true
false
false

可是為什么double aa = -19162431.1254;沒有匹配為true呢?
原來當數字位數很長時,系統會自動轉為科學計數法。所以aa=-1.91624311254E7.
所以我們需要使用java專門用於商業精度計數的類 BigDecimal.
我們需要new BigDecimal(str),但是呢,如果str為中文,會報異常。所以我用try catch捕捉異常。

正確的通用代碼(傳入包含中文、負數、位數很長的數字的字符串也能正常匹配):

/**
* 匹配是否為數字
* @param str 可能為中文,也可能是-19162431.1254,不使用BigDecimal的話,變成-1.91624311254E7
* @return
* @author yutao
* @date 2016年11月14日下午7:41:22
*/
public static boolean isNumeric(String str) {
// 該正則表達式可以匹配所有的數字 包括負數
Pattern pattern = Pattern.compile("-?[0-9]+(\\.[0-9]+)?");
String bigStr;
try {
bigStr = new BigDecimal(str).toString();
} catch (Exception e) {
return false;//異常 說明包含非數字。
}

Matcher isNum = pattern.matcher(bigStr); // matcher是全匹配
if (!isNum.matches()) {
return false;
}
return true;
}

=====2018年2月5日======start===

評論中的新思路

public static boolean isNumeric(String str) {
String bigStr;
try {
bigStr = new BigDecimal(str).toString();
} catch (Exception e) {
return false;//異常 說明包含非數字。
}
return true;
}

如果是數字,創建new BigDecimal()時肯定不會報錯,那就可以直接返回true啦!
=====2018年2月5日=====end====

======2018年3月5日=====start======
感謝評論中網友的糾錯:

-?[0-9]+\\.?[0-9]*這個表達式在匹配字符串1.、222.時,確實會出現問題。
網友的建議改為:-?[0-9]+(\\.[0-9]+)?。
測試后,確實是可以的!
======2018年3月5日=====end======

使用org.apache.commons.lang
public static boolean isNumeric(String str)Checks if the String contains only unicode digits. A decimal point is not a unicode digit and returns false.
null will return false. An empty String ("") will return true.
StringUtils.isNumeric(null) = false
StringUtils.isNumeric("") = true
StringUtils.isNumeric(" ") = false
StringUtils.isNumeric("123") = true
StringUtils.isNumeric("12 3") = false
StringUtils.isNumeric("ab2c") = false
StringUtils.isNumeric("12-3") = false
StringUtils.isNumeric("12.3") = false

Parameters:
str - the String to check, may be null
Returns:
true if only contains digits, and is non-null

第三種我沒有測試,網上說,也不能判斷負數。
又因為使用第三方的包,我懶得用,java原生就很好了。

====2018年3月5日=====
今天測試了org.apache.commons.lang3.StringUtils中的isNumeric,依舊不能判斷負數、帶小數點的數字。
對於第三方org.apache.commons.lang3包,是個好東西,但是也有很多bug的,用的時候多測測。

總結
肯定是使用第二種正則表達式計算啦!正則表達式用對地方啦,就不慢!
動不動就說正則太慢的人,是玩不6正則表達式的!

=====2018年2月5日======
可以不使用正則,直接通過是否有異常來判斷 —— 評論中網友給出的答案!
感覺可行(因為沒有實戰過,只是簡單的測試了下!)

======2018年3月5日=====start======
感謝網友提的建議,可以看出,我的測試用例沒有弄好;
如果依然要使用正則表達式的話,目前正確的是:-?[0-9]+(\\.[0-9]+)?。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM