如何在Java中检查string是否为数字

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

使用Apache Commons Lang 3.5及更高版本: NumberUtils.isCreatableStringUtils.isNumeric

使用Apache Commons Lang 3.4及以下版本: NumberUtils.isNumberStringUtils.isNumeric

您还可以使用StringUtils.isNumericSpace ,它为空string返回true ,并忽略string中的内部空格。 (链接的javadoc包含每个方法的详细示例。)

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

就像是:

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

但是,如果你正在调用这个函数,并且你期望很多的检查失败,因为不是一个数字,那么这个机制的性能就不会太好,因为你依靠抛出每个失败的exception,这是一个相当昂贵的操作。

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

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

不过要注意上面的RegEx机制,因为如果你使用的是非阿拉伯数字(即0到9之外的数字),它将会失败。 这是因为正则expression式的“\ d”部分只会匹配[0-9],并且在国际上不具有数字意义。 (感谢OregonGhost指出这一点!)

或者甚至另一种select是使用Java内置的java.text.NumberFormat对象来查看在parsingstring之后分析器位置是否在string的末尾。 如果是这样,我们可以假定整个string是数字的:

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

如果你在Android上,那么你应该使用:

 android.text.TextUtils.isDigitsOnly(CharSequence str) 

文档可以在这里find

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

正如@CraigTP在他的优秀答案中提到的,我也有类似的性能问题,使用exception来testingstring是否是数字。 所以我最终分裂了string,并使用java.lang.Character.isDigit()

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

根据Javadoc , Character.isDigit(char)将正确识别非拉丁数字。 在性能方面,我认为简单的N个比较(其中N是string中的字符数)比进行正则expression式匹配更具有计算效率。

更新:正如Jean-FrançoisCorbett在评论中所指出的那样,上面的代码只会validation正整数,这涵盖了我的大部分用例。 以下是根据系统中使用的默认语言环境正确validation小数的更新代码,假设小数点分隔符只在string中出现一次。

 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; } 

Java 8 lambdaexpression式。

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

Google的Guava库提供了一个很好的辅助方法: Ints.tryParse 。 您可以像Integer.parseInt一样使用它,但是如果string不parsing为有效的整数,它将返回null而不是抛出exception。 请注意,它返回Integer,而不是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 22 System.out.println(i2); // prints -1 

然而,就目前的版本 – “番石榴r11”而言,它仍然被标记为“贝塔”。

我没有对它进行基准testing。 看一下源代码有一些开销,但是最后他们使用了Character.digit(string.charAt(idx)) ,与上面的@Ibrahim的答案类似,但略有不同。 在实施过程中,封面没有exception处理的开销。

不要使用例外来validation您的值。 使用Util libs而不是像apache NumberUtils:

 NumberUtils.isNumber(myStringValue); 

为什么大家都在推动exception/正则expression式解决scheme?

虽然我可以理解大多数人使用try / catch都很好,但是如果你想经常这样做的话,这可能是非常重要的。

我在这里做的是采取正则expression式,parseNumber()方法和数组search方法,看看哪个是最有效的。 这一次,我只看整数。

 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 sign Array 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个字符或更less,每个string总是一个数字…在这种情况下,为什么甚至有一个检查?

总之,如果你经常用try / catch来碰到无效的数字,这是非常痛苦的,这是有道理的。 我总是遵循的一个重要规则是从不使用try / catch来实现程序stream 。 这是一个例子。

有趣的是,简单的如果char <0 || > 9写起来非常简单,易于记忆(并且应该以多种语言工作),并且几乎赢得了所有的testing场景。

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


对于那些想知道为什么我说容易记住字符排列的人来说,如果你知道没有负面的信号,你可以轻易地得到一些凝结的东西:

 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(...) 

不仅没用,因为你甚至不使用这个值,但是它浪费了处理时间,并增加了几纳秒的运行时间(这导致testing增加了100-200毫秒)。 我不明白为什么有人会这样做,因为它实际上是减less性能的额外工作。

你会认为这将被优化出来…虽然也许我应该检查字节码,看看编译器在做什么。 这并不能解释为什么它总是显示为更长的我虽然如果它以某种方式被优化了…因此,我不知道发生了什么事情。 作为一个说明:通过更长,我的意思是运行testing10000000次迭代,运行该程序多次(10倍+)总是表明它慢。

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

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

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

此外,它会拒绝任何数字与领先的“+”

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

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

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

你可以使用NumberFormat#parse

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

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

捕捉所有便捷方法,您可以使用任何types的分析器parsing任何string: isParsable(Object parser, String str) 。 parsing器可以是一个Class或一个object 。 这也可以让你使用自己编写的自定义分析器,并且应该为以前的场景工作,例如:

 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 methods for (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 method continue; // 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; } } 

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

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

这里是我的类来检查一个string是否是数字。 它还修复了数字string:

特征:

  1. 删除不必要的零[“12.0000000” – >“12”]
  2. 删除不必要的零[“12.0580000” – >“12.058”]
  3. 删除非数字字符[“12.00sdfsdf00” – >“12”]
  4. 处理负数string值[“-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 null if(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 dots for (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 begining double uglyMethod = Double.parseDouble(str); str = String.valueOf(uglyMethod); //Removes the .0 str = 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; } } 

一个运作良好的方法避免尝试捕捉和处理负数和科学记数法。

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

正则expression式匹配

这是另一个升级的“CraigTP”正则expression式与更多的validation匹配的例子。

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

正则expression式testing

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

例外是昂贵的,但在这种情况下RegEx需要更长的时间。 下面的代码显示了两个函数的简单testing – 一个使用exception,一个使用正则expression式。 在我的机器上,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); } } 

这就是为什么我喜欢.NET中的Try *方法。 除了像Java那样的传统Parse方法之外,还有一个TryParse方法。 我不擅长Java语法(out参数?),所以请把下面的代码当作一些伪代码。 它应该使概念清楚。

 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. } 
 // only int public static boolean isNumber(int num) { return (num >= 48 && c <= 57); // 0 - 9 } // is type of number including . - e E public 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 number public 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; } } 

这个检查的一个简单的例子:

 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 digit result = true; } else { result = false; break; } } } return result; } 

parsing它(即与Integer#parseInt ),只是捕捉exception。 =)

澄清:parseInt函数检查它是否可以在任何情况下(显然)parsing数字,如果你想parsing它,你不会实际执行parsing任何性能。

如果你不想parsing它(或者非常非常罕见地parsing它),你可能希望做不同的事情。

//请检查下面的代码

 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; } 

这里有两种方法可能工作。 (不使用例外)。 注意:默认情况下,Java是按值传递的,String的值是String的对象数据的地址。 所以,当你在做什么

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

您已将input值更改为不含空格。 如果需要,可以删除该行。

 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我刚刚做到了,我认为它需要进一步的testing,以确保它的工作。

 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; } 

I modified CraigTP's solution to accept scientific notation and both dot and comma as decimal separators as well

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

 var re = new RegExp("^-?\d+([,\.]\d+)?([eE]-?\d+)?$"); re.test("-6546"); // true re.test("-6546355e-4456"); // true re.test("-6546.355e-4456"); // true, though debatable re.test("-6546.35.5e-4456"); // false re.test("-6546.35.5e-4456.6"); // false 

You can use the java.util.Scanner object.

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

You can use NumberUtils.isCreatable() from Apache Commons Lang .

Since NumberUtils.isNumber will be deprecated in 4.0, so use NumberUtils.isCreatable() instead.

This is the fastest way i know to check if String is Number or not:

 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=='1' || c=='2' || c=='3' || c=='4' || c=='5' || c=='6' || c=='7' || c=='8' || c=='9'; } 

I think the only way to reliably tell if a string is a number, is to parse it. So I would just parse it, and if it's a number, you get the number in an int for free!

You could use BigDecimal if the string may contain decimals:

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

If you want to do the check using a regex you should create a final static Pattern object, that way the regex only needs to be compiled once. Compiling the regex takes about as long as performing the match so by taking this precaution you'll cut the execution time of the method in half.

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

I'm assuming a number is a string with nothing but decimal digits in it, possibly a + or – sign at the start and at most one decimal point (not at the end) and no other characters (including commas, spaces, numbers in other counting systems, Roman numerals, hieroglyphs).

This solution is succinct and pretty fast but you can shave a couple of milliseconds per million invocations by doing it like this

 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 digit return false; } else if (c == '.') { if (++dotCount > 1) { return false; } } else if (i != 0 || c != '+' && c != '-') {//+ or - allowed at start return false; } } } return true; }