如何检查一个字符串是否是数字在Java

在解析String之前如何检查它是否是一个数字?

1795287 次浏览

解析它(即使用Integer#parseInt)并简单地捕获异常。=)

澄清一下:parseInt函数检查它是否可以在任何情况下(显然)解析数字,如果你想解析它,你不会因为实际进行解析而受到任何性能影响。

如果你不想解析它(或者非常非常少地解析它),你可能希望以不同的方式来做。

您可以使用NumberFormat#parse

try{NumberFormat.getInstance().parse(value);}catch(ParseException e){// Not a number.}

我认为可靠地判断字符串是否是数字的唯一方法是解析它。所以我会解析它,如果它是一个数字,你可以免费获得int中的数字!

这通常是通过一个简单的用户定义函数(即Roll-my-own“isNumery”函数)完成的。

类似:

public static boolean isNumeric(String str) {try {Double.parseDouble(str);return true;} catch(NumberFormatException e){return false;}}

但是,如果您经常调用此函数,并且由于不是数字而期望许多检查失败,那么此机制的性能不会很好,因为您依赖于每次失败都会抛出异常,这是一个相当昂贵的操作。

另一种方法可能是使用正则表达式来检查作为数字的有效性:

public static boolean isNumeric(String str) {return str.matches("-?\\d+(\\.\\d+)?");  //match a number with optional '-' and decimal.}

不过,请注意上述RegEx机制,因为如果您使用的是非阿拉伯数字(即0到9以外的数字),它将失败。这是因为RegEx的“\d”部分只会匹配[0-9],并且实际上无法在国际上识别数字。(感谢OregonGhost指出这一点!)

或者另一种选择是使用Java的内置java.text.NumberFormat对象来查看解析字符串后解析器的位置是否在字符串的末尾。如果是,我们可以假设整个字符串是数字的:

public static boolean isNumeric(String str) {ParsePosition pos = new ParsePosition(0);NumberFormat.getInstance().parse(str, pos);return str.length() == pos.getIndex();}

这就是为什么我喜欢. NET中的try*方法。除了像Java的传统Parse方法外,你还有一个TryParse方法。我不擅长Java语法(输出参数?),所以请将以下内容视为某种伪代码。不过,它应该会使概念清晰。

boolean parseInteger(String s, out int number){try {number = Integer.parseInt(myString);return true;} catch(NumberFormatException e) {return false;}}

用法:

int num;if (parseInteger("23", out num)) {// Do something with num.}

正如@CraigTP在他出色的回答中提到的,我在使用Exceptions来测试字符串是否为数字时也有类似的性能问题。所以我最终拆分字符串并使用java.lang.Character.isDigit()

public static boolean isNumeric(String str){for (char c : str.toCharArray()){if (!Character.isDigit(c)) return false;}return true;}

根据的javadocCharacter.isDigit(char)将正确识别非拉丁数字。就性能而言,我认为简单的N次比较,其中N是字符串中的字符数,比进行正则表达式匹配更具计算效率。

更新:正如Jean-François Corbett在评论中指出的那样,上述代码只会验证正整数,这涵盖了我的大部分用例。以下是更新的代码,它根据系统中使用的默认语言环境正确验证十进制数字,假设十进制分隔符在字符串中只出现一次。

public static boolean isStringNumeric( String str ){DecimalFormatSymbols currentLocaleSymbols = DecimalFormatSymbols.getInstance();char localeMinusSign = currentLocaleSymbols.getMinusSign();
if ( !Character.isDigit( str.charAt( 0 ) ) && str.charAt( 0 ) != localeMinusSign ) return false;
boolean isDecimalSeparatorFound = false;char localeDecimalSeparator = currentLocaleSymbols.getDecimalSeparator();
for ( char c : str.substring( 1 ).toCharArray() ){if ( !Character.isDigit( c ) ){if ( c == localeDecimalSeparator && !isDecimalSeparatorFound ){isDecimalSeparatorFound = true;continue;}return false;}}return true;}
public static boolean isNumeric(String str){return str.matches("-?\\d+(.\\d+)?");}

CraigTP的正则表达式(如上所示)会产生一些误报。例如“23y4”将被计为一个数字,因为“.”匹配任何字符而不是小数点。

它也会拒绝任何带有前导“+”的数字

避免这两个小问题的替代方案是

public static boolean isNumeric(String str){return str.matches("[+-]?\\d*(\\.\\d+)?");}

这是我对这个问题的回答。

一个捕获所有方便的方法,您可以使用它来解析任何类型的解析器的任何String:isParsable(Object parser, String str)。解析器可以是Classobject。这也将允许您使用您编写的自定义解析器,并且应该适用于任何场景,例如:

isParsable(Integer.class, "11");isParsable(Double.class, "11.11");Object dateFormater = new java.text.SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss z");isParsable(dateFormater, "2001.07.04 AD at 12:08:56 PDT");

这是我的代码,包含方法描述。

import java.lang.reflect.*;
/*** METHOD: isParsable<p><p>** This method will look through the methods of the specified <code>from</code> parameter* looking for a public method name starting with "parse" which has only one String* parameter.<p>** The <code>parser</code> parameter can be a class or an instantiated object, eg:* <code>Integer.class</code> or <code>new Integer(1)</code>. If you use a* <code>Class</code> type then only static methods are considered.<p>** When looping through potential methods, it first looks at the <code>Class</code> associated* with the <code>parser</code> parameter, then looks through the methods of the parent's class* followed by subsequent ancestors, using the first method that matches the criteria specified* above.<p>** This method will hide any normal parse exceptions, but throws any exceptions due to* programmatic errors, eg: NullPointerExceptions, etc. If you specify a <code>parser</code>* parameter which has no matching parse methods, a NoSuchMethodException will be thrown* embedded within a RuntimeException.<p><p>** Example:<br>* <code>isParsable(Boolean.class, "true");<br>* isParsable(Integer.class, "11");<br>* isParsable(Double.class, "11.11");<br>* Object dateFormater = new java.text.SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss z");<br>* isParsable(dateFormater, "2001.07.04 AD at 12:08:56 PDT");<br></code>* <p>** @param parser    The Class type or instantiated Object to find a parse method in.* @param str   The String you want to parse** @return true if a parse method was found and completed without exception* @throws java.lang.NoSuchMethodException If no such method is accessible*/public static boolean isParsable(Object parser, String str) {Class theClass = (parser instanceof Class? (Class)parser: parser.getClass());boolean staticOnly = (parser == theClass), foundAtLeastOne = false;Method[] methods = theClass.getMethods();
// Loop over methodsfor (int index = 0; index < methods.length; index++) {Method method = methods[index];
// If method starts with parse, is public and has one String parameter.// If the parser parameter was a Class, then also ensure the method is static.if(method.getName().startsWith("parse") &&(!staticOnly || Modifier.isStatic(method.getModifiers())) &&Modifier.isPublic(method.getModifiers()) &&method.getGenericParameterTypes().length == 1 &&method.getGenericParameterTypes()[0] == String.class){try {foundAtLeastOne = true;method.invoke(parser, str);return true; // Successfully parsed without exception} catch (Exception exception) {// If invoke problem, try a different method/*if(!(exception instanceof IllegalArgumentException) &&!(exception instanceof IllegalAccessException) &&!(exception instanceof InvocationTargetException))continue; // Look for other parse methods*/
// Parse method refuses to parse, look for another different methodcontinue; // Look for other parse methods}}}
// No more accessible parse method could be found.if(foundAtLeastOne) return false;else throw new RuntimeException(new NoSuchMethodException());}

/*** METHOD: willParse<p><p>** A convienence method which calls the isParseable method, but does not throw any exceptions* which could be thrown through programatic errors.<p>** Use of {@link #isParseable(Object, String) isParseable} is recommended for use so programatic* errors can be caught in development, unless the value of the <code>parser</code> parameter is* unpredictable, or normal programtic exceptions should be ignored.<p>** See {@link #isParseable(Object, String) isParseable} for full description of method* usability.<p>** @param parser    The Class type or instantiated Object to find a parse method in.* @param str   The String you want to parse** @return true if a parse method was found and completed without exception* @see #isParseable(Object, String) for full description of method usability*/public static boolean willParse(Object parser, String str) {try {return isParsable(parser, str);} catch(Throwable exception) {return false;}}

谷歌的Guava库提供了一个很好的帮助方法来做到这一点:Ints.tryParse。你像Integer.parseInt一样使用它,但如果字符串没有解析为有效整数,它会返回null而不是抛出异常。请注意,它返回的是整数,而不是int,所以你必须将/autobox它转换回int。

示例:

String s1 = "22";String s2 = "22.2";Integer oInt1 = Ints.tryParse(s1);Integer oInt2 = Ints.tryParse(s2);
int i1 = -1;if (oInt1 != null) {i1 = oInt1.intValue();}int i2 = -1;if (oInt2 != null) {i2 = oInt2.intValue();}
System.out.println(i1);  // prints 22System.out.println(i2);  // prints -1

但是,截至当前版本-Guava r11-它仍然标记为@Beta。

我还没有对它进行基准测试。查看源代码,大量的完整性检查会产生一些开销,但最终他们使用Character.digit(string.charAt(idx)),类似,但与上面@Ibrahim的答案略有不同。在他们的实现中,没有异常处理开销。

如果字符串可能包含小数,您可以使用BigDecimal

try {new java.math.BigInteger(testString);} catch(NumberFormatException e) {throw new RuntimeException("Not a valid number");}

Apache Commons Lang 3.5及以上:NumberUtils.isCreatableStringUtils.isNumeric

Apache Commons Lang 3.4及以下:NumberUtils.isNumberStringUtils.isNumeric

您还可以使用StringUtils.isNumericSpace,它返回空字符串的true并忽略字符串中的内部空格。另一种方法是使用NumberUtils.isParsable,它基本上根据Java检查数字是否可解析。(链接的javadocs包含每个方法的详细示例。)

// only intpublic static boolean isNumber(int num){return (num >= 48 && c <= 57); // 0 - 9}
// is type of number including . - e Epublic static boolean isNumber(String s){boolean isNumber = true;for(int i = 0; i < s.length() && isNumber; i++){char c = s.charAt(i);isNumber = isNumber & ((c >= '0' && c <= '9') || (c == '.') || (c == 'e') || (c == 'E') || (c == ''));}return isInteger;}
// is type of numberpublic static boolean isInteger(String s){boolean isInteger = true;for(int i = 0; i < s.length() && isInteger; i++){char c = s.charAt(i);isInteger = isInteger & ((c >= '0' && c <= '9'));}return isInteger;}
public static boolean isNumeric(String s){try{Double.parseDouble(s);return true;}catch (Exception e){return false;}}

这里有两个可能有效的方法。(不使用异常)。注意:默认情况下,Java是一个按值传递,String的值是String对象数据的地址。所以,当你做

stringNumber = stringNumber.replaceAll(" ", "");

您已将输入值更改为没有空格。如果你愿意,你可以删除这条线。

private boolean isValidStringNumber(String stringNumber){if(stringNumber.isEmpty()){return false;}
stringNumber = stringNumber.replaceAll(" ", "");
char [] charNumber = stringNumber.toCharArray();for(int i =0 ; i<charNumber.length ;i++){if(!Character.isDigit(charNumber[i])){return false;}}return true;}

这是另一种方法,如果你想允许浮点数据称这种方法允许表单中的数字通过1,123,123,123,123,123.123我刚刚做了,我认为它需要进一步的测试,以确保它的工作。

private boolean isValidStringTrueNumber(String stringNumber){if(stringNumber.isEmpty()){return false;}
stringNumber = stringNumber.replaceAll(" ", "");int countOfDecimalPoint = 0;boolean decimalPointPassed = false;boolean commaFound = false;int countOfDigitsBeforeDecimalPoint = 0;int countOfDigitsAfterDecimalPoint =0 ;int commaCounter=0;int countOfDigitsBeforeFirstComma = 0;
char [] charNumber = stringNumber.toCharArray();for(int i =0 ; i<charNumber.length ;i++){if((commaCounter>3)||(commaCounter<0)){return false;}if(!Character.isDigit(charNumber[i]))//Char is not a digit.{if(charNumber[i]==','){if(decimalPointPassed){return false;}commaFound = true;//check that next three chars are only digits.commaCounter +=3;}else if(charNumber[i]=='.'){decimalPointPassed = true;countOfDecimalPoint++;}else{return false;}}else //Char is a digit.{if ((commaCounter>=0)&&(commaFound)){if(!decimalPointPassed){commaCounter--;}}
if(!commaFound){countOfDigitsBeforeFirstComma++;}
if(!decimalPointPassed){countOfDigitsBeforeDecimalPoint++;}else{countOfDigitsAfterDecimalPoint++;}}}if((commaFound)&&(countOfDigitsBeforeFirstComma>3)){return false;}if(countOfDecimalPoint>1){return false;}
if((decimalPointPassed)&&((countOfDigitsBeforeDecimalPoint==0)||(countOfDigitsAfterDecimalPoint==0))){return false;}return true;}

如果您使用的是Android,则应该使用:

android.text.TextUtils.isDigitsOnly(CharSequence str)

留档可以在这里找到

大多数人都可以“重新编程”(同样的事情)。

我修改了CraigTP的解决方案以接受科学记数法以及点和逗号作为小数分隔符

^-?\d+([,\.]\d+)?([eE]-?\d+)?$

示例

var re = new RegExp("^-?\d+([,\.]\d+)?([eE]-?\d+)?$");re.test("-6546"); // truere.test("-6546355e-4456"); // truere.test("-6546.355e-4456"); // true, though debatablere.test("-6546.35.5e-4456"); // falsere.test("-6546.35.5e-4456.6"); // false
import java.util.Scanner;
public class TestDemo {public static void main(String[] args) {boolean flag = true;Scanner sc = new Scanner(System.in);System.out.println("Enter the String:");String str = sc.nextLine();
for (int i = 0; i < str.length(); i++) {if(str.charAt(i) > 48 && str.charAt(i) < 58) {flag = false;break;}}
if(flag == true) {System.out.println("String is a valid String.");} else {System.out.println("String contains number.");}}}

如果您使用Java开发Android应用程序,您可以使用TextUtils.isDigitsOnly函数。

一种性能良好的方法,避免尝试捕获和处理负数和科学记数法。

Pattern PATTERN = Pattern.compile( "^(-?0|-?[1-9]\\d*)(\\.\\d+)?(E\\d+)?$" );
public static boolean isNumeric( String value ){return value != null && PATTERN.matcher( value ).matches();}

如果你想使用正则表达式进行检查,你应该创建一个最终的静态Pattern对象,这样正则表达式只需要编译一次。编译正则表达式大约需要执行匹配的时间,因此通过采取这种预防措施,你可以将方法的执行时间缩短一半。

final static Pattern NUMBER_PATTERN = Pattern.compile("[+-]?\\d*\\.?\\d+");
static boolean isNumber(String input) {Matcher m = NUMBER_PATTERN.matcher(input);return m.matches();}

我假设一个数字是一个只有十进制数字的字符串,可能是开头的+或-符号,最多一个小数点(不是结尾),没有其他字符(包括逗号,空格,其他计数系统中的数字,罗马数字,象形文字)。

这个解决方案简洁且非常快,但您可以通过这样做来节省每百万次调用的几毫秒

static boolean isNumber(String s) {final int len = s.length();if (len == 0) {return false;}int dotCount = 0;for (int i = 0; i < len; i++) {char c = s.charAt(i);if (c < '0' || c > '9') {if (i == len - 1) {//last character must be digitreturn false;} else if (c == '.') {if (++dotCount > 1) {return false;}} else if (i != 0 || c != '+' && c != '-') {//+ or - allowed at startreturn false;}
}}return true;}

要仅匹配只包含ASCII数字的正十进制整数,请使用:

public static boolean isNumeric(String maybeNumeric) {return maybeNumeric != null && maybeNumeric.matches("[0-9]+");}

这是此检查的一个简单示例:

public static boolean isNumericString(String input) {boolean result = false;
if(input != null && input.length() > 0) {char[] charArray = input.toCharArray();
for(char c : charArray) {if(c >= '0' && c <= '9') {// it is a digitresult = true;} else {result = false;break;}}}
return result;}

这是我的类,用于检查字符串是否为数字。它还修复数字字符串:

产品特点:

  1. 删除不必要的零["12.0000000"->"12"]
  2. 删除不必要的零["12.0580000"->"12.058"]
  3. 删除非数字字符["12.00sdfsdf00"->"12"]
  4. 处理负字符串值["-12,020000" -> "-12.02"]
  5. 删除多个点["-12.0.20.000 " -> "-12.02"]
  6. 没有额外的库,只是标准的Java

给你…

public class NumUtils {/*** Transforms a string to an integer. If no numerical chars returns a String "0".** @param str* @return retStr*/static String makeToInteger(String str) {String s = str;double d;d = Double.parseDouble(makeToDouble(s));int i = (int) (d + 0.5D);String retStr = String.valueOf(i);System.out.printf(retStr + "   ");return retStr;}
/*** Transforms a string to an double. If no numerical chars returns a String "0".** @param str* @return retStr*/static String makeToDouble(String str) {
Boolean dotWasFound = false;String orgStr = str;String retStr;int firstDotPos = 0;Boolean negative = false;
//check if str is nullif(str.length()==0){str="0";}
//check if first sign is "-"if (str.charAt(0) == '-') {negative = true;}
//check if str containg any number or else set the string to '0'if (!str.matches(".*\\d+.*")) {str = "0";}
//Replace ',' with '.'  (for some european users who use the ',' as decimal separator)str = str.replaceAll(",", ".");str = str.replaceAll("[^\\d.]", "");
//Removes the any second dotsfor (int i_char = 0; i_char < str.length(); i_char++) {if (str.charAt(i_char) == '.') {dotWasFound = true;firstDotPos = i_char;break;}}if (dotWasFound) {String befDot = str.substring(0, firstDotPos + 1);String aftDot = str.substring(firstDotPos + 1, str.length());aftDot = aftDot.replaceAll("\\.", "");str = befDot + aftDot;}
//Removes zeros from the beginingdouble uglyMethod = Double.parseDouble(str);str = String.valueOf(uglyMethod);
//Removes the .0str = str.replaceAll("([0-9])\\.0+([^0-9]|$)", "$1$2");
retStr = str;
if (negative) {retStr = "-"+retStr;}
return retStr;
}
static boolean isNumeric(String str) {try {double d = Double.parseDouble(str);} catch (NumberFormatException nfe) {return false;}return true;}
}

试试这个:

public  boolean isNumber(String str){short count = 0;char chc[]  = {'0','1','2','3','4','5','6','7','8','9','.','-','+'};for (char c : str.toCharArray()){for (int i = 0;i < chc.length;i++){if( c  == chc[i]){count++;}}}if (count != str.length() )return false;elsereturn true;}

为什么每个人都在推动异常/正则表达式解决方案?

虽然我可以理解大多数人都可以使用try/catch,但如果你想经常这样做……它可能会非常费力。

我在这里所做的是采用正则表达式、parseNumber()方法和数组搜索方法来查看哪种方法最有效。这次,我只看了整数。

public static boolean isNumericRegex(String str) {if (str == null)return false;return str.matches("-?\\d+");}
public static boolean isNumericArray(String str) {if (str == null)return false;char[] data = str.toCharArray();if (data.length <= 0)return false;int index = 0;if (data[0] == '-' && data.length > 1)index = 1;for (; index < data.length; index++) {if (data[index] < '0' || data[index] > '9') // Character.isDigit() can go here too.return false;}return true;}
public static boolean isNumericException(String str) {if (str == null)return false;try {/* int i = */ Integer.parseInt(str);} catch (NumberFormatException nfe) {return false;}return true;}

我得到的速度结果是:

Done with: for (int i = 0; i < 10000000; i++)...
With only valid numbers ("59815833" and "-59815833"):Array numeric took 395.808192 ms [39.5808192 ns each]Regex took 2609.262595 ms [260.9262595 ns each]Exception numeric took 428.050207 ms [42.8050207 ns each]// Negative signArray numeric took 355.788273 ms [35.5788273 ns each]Regex took 2746.278466 ms [274.6278466 ns each]Exception numeric took 518.989902 ms [51.8989902 ns each]// Single value ("1")Array numeric took 317.861267 ms [31.7861267 ns each]Regex took 2505.313201 ms [250.5313201 ns each]Exception numeric took 239.956955 ms [23.9956955 ns each]// With Character.isDigit()Array numeric took 400.734616 ms [40.0734616 ns each]Regex took 2663.052417 ms [266.3052417 ns each]Exception numeric took 401.235906 ms [40.1235906 ns each]
With invalid characters ("5981a5833" and "a"):Array numeric took 343.205793 ms [34.3205793 ns each]Regex took 2608.739933 ms [260.8739933 ns each]Exception numeric took 7317.201775 ms [731.7201775 ns each]// With a single character ("a")Array numeric took 291.695519 ms [29.1695519 ns each]Regex took 2287.25378 ms [228.725378 ns each]Exception numeric took 7095.969481 ms [709.5969481 ns each]
With null:Array numeric took 214.663834 ms [21.4663834 ns each]Regex took 201.395992 ms [20.1395992 ns each]Exception numeric took 233.049327 ms [23.3049327 ns each]Exception numeric took 6603.669427 ms [660.3669427 ns each] if there is no if/null check

免责声明:我不是说这些方法是100%优化的,它们只是为了演示数据

当且仅当数字为4个字符或更少,并且每个字符串都是总是一个数字时,异常才会获胜……在这种情况下,为什么还要检查呢?

简而言之,如果你在try/catch中经常遇到无效的数字,这是非常痛苦的,这是有道理的。我一直遵循的一个重要规则是永远不要对程序流使用try/catch。这是一个例子。

有趣的是,简单的if char<0||>9编写起来非常简单,易于记忆(并且应该适用于多种语言),并且几乎赢得了所有测试场景。

唯一的缺点是我猜Integer.parseInt()可能会处理非ASCII数字,而数组搜索方法不会。


对于那些想知道为什么我说很容易记住字符数组1的人来说,如果你知道没有负号,你可以很容易地用这样浓缩的东西逃脱惩罚:

public static boolean isNumericArray(String str) {if (str == null)return false;for (char c : str.toCharArray())if (c < '0' || c > '9')return false;return true;

最后,作为最后的说明,我对已接受的示例中所有投票数都上升的同化运算符感到好奇。添加赋值

double d = Double.parseDouble(...)

因为你甚至不使用这个值,所以它不仅毫无用处,而且会浪费流转时长并将运行时间增加几纳秒(这导致测试增加了100-200毫秒)。我不明白为什么有人会这样做,因为这实际上是降低性能的额外工作。

你会认为这会被优化掉……尽管也许我应该检查字节码并看看编译器在做什么。这并不能解释为什么它总是对我来说显示为更长,尽管它以某种方式被优化了……因此我想知道发生了什么。作为一个注释:更长,我的意思是运行10000000次迭代的测试,并且运行该程序多次(10x+)总是表明它更慢。

编辑:更新了Character.isDigit()的测试

正则表达式匹配

这是另一个升级的“CraigTP”正则表达式与更多验证匹配的示例。

public static boolean isNumeric(String str){return str.matches("^(?:(?:\\-{1})?\\d+(?:\\.{1}\\d+)?)$");}
  1. 只允许一个负号-,并且必须在开头。
  2. 负号后面必须有数字。
  3. 只允许一个小数点.
  4. 小数点后必须有数字。

正则表达式测试

1                  --                   **VALID**1.                 --                   INVALID1..                --                   INVALID1.1                --                   **VALID**1.1.1              --                   INVALID
-1                 --                   **VALID**--1                --                   INVALID-1.                --                   INVALID-1.1               --                   **VALID**-1.1.1             --                   INVALID

异常是昂贵的,但在这种情况下,RegEx需要更长的时间。下面的代码显示了两个函数的简单测试——一个使用异常,一个使用正则表达式。在我的机器上,RegEx版本比异常慢10倍。

import java.util.Date;

public class IsNumeric {
public static boolean isNumericOne(String s) {return s.matches("-?\\d+(\\.\\d+)?");  //match a number with optional '-' and decimal.}
public static boolean isNumericTwo(String s) {try {Double.parseDouble(s);return true;} catch (Exception e) {return false;}}
public static void main(String [] args) {
String test = "12345.F";
long before = new Date().getTime();for(int x=0;x<1000000;++x) {//isNumericTwo(test);isNumericOne(test);}long after = new Date().getTime();
System.out.println(after-before);
}
}
String text="hello 123";if(Pattern.matches([0-9]+))==trueSystem.out.println("String"+text);

您可以使用java.util.Scanner对象。

public static boolean isNumeric(String inputData) {Scanner sc = new Scanner(inputData);return sc.hasNextInt();}

<强>不要使用异常来验证您的值。像apache NumberUtils一样使用Utillibs:

NumberUtils.isNumber(myStringValue);

编辑

请注意,如果您的字符串以0开头,NumberUtils会将您的值解释为十六进制。

NumberUtils.isNumber("07") //trueNumberUtils.isNumber("08") //false

Java8个lambda表达式。

String someString = "123123";boolean isNumeric = someString.chars().allMatch( Character::isDigit );

Java8流,lambda表达式,功能接口

处理的所有案件(字符串空,字符串空等

String someString = null; // something="", something="123abc", something="123123"
boolean isNumeric = Stream.of(someString).filter(s -> s != null && !s.isEmpty()).filter(Pattern.compile("\\D").asPredicate().negate()).mapToLong(Long::valueOf).boxed().findAny().isPresent();

//请检查下面的代码

public static boolean isDigitsOnly(CharSequence str) {final int len = str.length();for (int i = 0; i < len; i++) {if (!Character.isDigit(str.charAt(i))) {return false;}}return true;}

您可以使用Apache Commons Lang中的NumberUtils.is创建()。

由于NumberUtils.is将在4.0中被弃用,因此请改用NumberUtils.isCre的()。

这是我知道的检查String是否为Number的最快方法:

public static boolean isNumber(String str){int i=0, len=str.length();boolean a=false,b=false,c=false, d=false;if(i<len && (str.charAt(i)=='+' || str.charAt(i)=='-')) i++;while( i<len && isDigit(str.charAt(i)) ){ i++; a=true; }if(i<len && (str.charAt(i)=='.')) i++;while( i<len && isDigit(str.charAt(i)) ){ i++; b=true; }if(i<len && (str.charAt(i)=='e' || str.charAt(i)=='E') && (a || b)){ i++; c=true; }if(i<len && (str.charAt(i)=='+' || str.charAt(i)=='-') && c) i++;while( i<len && isDigit(str.charAt(i)) ){ i++; d=true;}return i==len && (a||b) && (!c || (c && d));}static boolean isDigit(char c){return c>='0' && c<='9';}

并行检查非常长的字符串,使用IntStream

在Java8中,以下测试给定string的所有字符是否都在'0'到'9'之间。注意空字符串被接受:

string.chars().unordered().parallel().allMatch( i -> '0' <= i && '9' >= i )

我已经说明了在不使用任何API的情况下检查数字和小数的一些条件,

检查固定长度1位数

Character.isDigit(char)

检查固定长度编号(假设长度为6)

String number = "132452";if(number.matches("([0-9]{6})"))System.out.println("6 digits number identified");

检查之间的可变长度数(假设长度为4到6)

//  {n,m}  n <= length <= mString number = "132452";if(number.matches("([0-9]{4,6})"))System.out.println("Number Identified between 4 to 6 length");
String number = "132";if(!number.matches("([0-9]{4,6})"))System.out.println("Number not in length range or different format");

检查可变长度十进制数之间(假设4到7长度)

//  It will not count the '.' (Period) in lengthString decimal = "132.45";if(decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))System.out.println("Numbers Identified between 4 to 7");
String decimal = "1.12";if(decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))System.out.println("Numbers Identified between 4 to 7");
String decimal = "1234";if(decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))System.out.println("Numbers Identified between 4 to 7");
String decimal = "-10.123";if(decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))System.out.println("Numbers Identified between 4 to 7");
String decimal = "123..4";if(!decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))System.out.println("Decimal not in range or different format");
String decimal = "132";if(!decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))System.out.println("Decimal not in range or different format");
String decimal = "1.1";if(!decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))System.out.println("Decimal not in range or different format");

希望它能帮助很多人。

如果您使用以下方法进行检查:

public static boolean isNumeric(String str) {NumberFormat formatter = NumberFormat.getInstance();ParsePosition pos = new ParsePosition(0);formatter.parse(str, pos);return str.length() == pos.getIndex();}

那么非常长的String的输入会发生什么,比如我称之为这个方法:

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

结果是“true”,也是一个太大的数字!同样的事情会发生,如果你使用正则表达式检查!所以我宁愿使用“解析”方法来检查,像这样:

public static boolean isNumeric(String str) {try {int number = Integer.parseInt(str);return true;} catch (Exception e) {return false;}}

结果是我所期望的!

我们可以尝试用("")即空格替换给定字符串中的所有数字,如果在此之后字符串的长度为零,那么我们可以说给定字符串仅包含数字。示例:

boolean isNumber(String str){if(str.length() == 0)return false; //To check if string is empty        
if(str.charAt(0) == '-')str = str.replaceFirst("-","");// for handling -ve numbers    
System.out.println(str);        
str = str.replaceFirst("\\.",""); //to check if it contains more than one decimal points        
if(str.length() == 0)return false; // to check if it is empty string after removing -ve sign and decimal pointSystem.out.println(str);        
return str.replaceAll("[0-9]","").length() == 0;}

基于我自己写的其他答案,它不使用模式或异常检查的解析。

它检查最多一个减号,并检查最多一个小数点。

以下是一些例子及其结果:

"1","-1","-1.5"和"-1.556"返回true

"1…5","1A.5","1.5D", "-" 和"--1"返回false

注意:如果需要,您可以修改它以接受Locale参数并将其传递给DecimalFormatSymbols.getInstance()调用以使用特定的Locale而不是当前的Locale。

 public static boolean isNumeric(final String input) {//Check for null or blank stringif(input == null || input.isBlank()) return false;
//Retrieve the minus sign and decimal separator characters from the current Localefinal var localeMinusSign = DecimalFormatSymbols.getInstance().getMinusSign();final var localeDecimalSeparator = DecimalFormatSymbols.getInstance().getDecimalSeparator();
//Check if first character is a minus signfinal var isNegative = input.charAt(0) == localeMinusSign;//Check if string is not just a minus signif (isNegative && input.length() == 1) return false;
var isDecimalSeparatorFound = false;
//If the string has a minus sign ignore the first characterfinal var startCharIndex = isNegative ? 1 : 0;
//Check if each character is a number or a decimal separator//and make sure string only has a maximum of one decimal separatorfor (var i = startCharIndex; i < input.length(); i++) {if(!Character.isDigit(input.charAt(i))) {if(input.charAt(i) == localeDecimalSeparator && !isDecimalSeparatorFound) {isDecimalSeparatorFound = true;} else return false;}}return true;}
private static Pattern p = Pattern.compile("^[0-9]*$");
public static boolean isNumeric(String strNum) {if (strNum == null) {return false;}return p.matcher(strNum).find();}

对于非负数,使用此

public boolean isNonNegativeNumber(String str) {return str.matches("\\d+");}

对于任何数字使用此

public boolean isNumber(String str) {return str.matches("-?\\d+");}