39 Pregunta: Cómo verificar si una cadena es numérica en Java

pregunta creada en Sun, Nov 29, 2015 12:00 AM

¿Cómo verificarías si una Cadena era un número antes de analizarla?

    
799
  1. Todas las soluciones propuestas con expresiones regulares no funcionarán para números hexadecimales.
    2012-02-17 12: 52: 02Z
  2. y pasar una cadena nula en la función de coincidencias (...) lanzará la excepción NullPointer.
    2016-04-14 07: 31: 20Z
  3. Vea la respuesta de Max Malysh para una solución concisa de Java 8 sin bibliotecas de terceros.
    2016-04-28 19: 50: 42Z
  4. @ Las cadenas nulas de HiteshSahu parecen manejarse con gracia en la última versión (incluyendo Java 6.xy 7.x)
    2016-10-06 06: 27: 45Z
  5. Todas las soluciones propuestas para usar Integer.parseInt() no analizarán los números móviles con NumberFormatException.
    2017-03-16 07: 24: 04Z
30 Respuestas                              30                         

Con Apache Commons Lang 3.5 y superior: NumberUtils.isCreatable o StringUtils.isNumeric .

Con Apache Commons Lang 3.4 y debajo: NumberUtils.isNumber o StringUtils.isNumeric .

También puede usar StringUtils.isNumericSpace que devuelve true para cadenas vacías e ignora los espacios internos de la cadena. Otra forma es usar StringUtils.isParsable que básicamente verifica que el número se pueda analizar de acuerdo con Java. (Los javadocs vinculados contienen ejemplos detallados para cada método).

    
633
2019-01-25 13: 09: 31Z
  1. + 1 Por qué reinventar la rueda.
    2012-11-15 22: 54: 40Z
  2. StringUtils.isNumeric() probablemente no sería apropiado aquí ya que solo comprueba si la cadena es una secuencia de dígitos. Estaría bien para la mayoría de los ints, pero no así para los números con decimales, separadores de grupo, etc.
    2013-02-08 23: 19: 52Z
  3. reinventa la rueda porque no incluyes toda una biblioteca porque necesitas una función de 3 líneas en un solo lugar.
    2014-09-18 12: 34: 42Z
  4. ¿Vale la pena agregar una biblioteca entera para esta función? Obviamente, si se usa con otras cosas que son geniales, pero probablemente sea excesivo considerando que las personas han resuelto esto en una sola línea dede.
    2015-03-30 00: 47: 20Z
  5. No funciona con negativos. Y la mitad de todos los números son negativos, así que ...
    2017-06-30 16: 58: 27Z

Esto generalmente se realiza con una función simple definida por el usuario (es decir, función "isNumeric" de rollo propio).

Algo como:

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

Sin embargo, si está llamando mucho a esta función, y espera que muchas de las comprobaciones falle debido a que no es un número, el rendimiento de este mecanismo no será muy bueno, ya que depende de las excepciones que se lanzan para Cada falla, que es una operación bastante costosa.

Un enfoque alternativo puede ser usar una expresión regular para verificar la validez de ser un número:

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

Sin embargo, tenga cuidado con el mecanismo RegEx anterior, ya que fallará si utiliza dígitos no árabes (es decir, números distintos del 0 al 9). Esto se debe a que la parte "\d" del RegEx solo coincidirá con [0-9] y, de hecho, no tiene conocimiento internacional numérico. (¡Gracias a OregonGhost por señalar esto!)

O incluso otra alternativa es usar el objeto java.text.NumberFormat incorporado de Java para ver si, después de analizar la cadena, la posición del analizador está al final de la cadena. Si es así, podemos asumir que toda la cadena es numérica:

 
public static boolean isNumeric(String str) {
  NumberFormat formatter = NumberFormat.getInstance();
  ParsePosition pos = new ParsePosition(0);
  formatter.parse(str, pos);
  return str.length() == pos.getIndex();
}
    
852
2019-03-02 09: 27: 34Z
  1. ¿\d en Java Regex solo coincide con los dígitos latinos? Si es como las expresiones regulares de .NET, se encontrará con un problema con otros dígitos (por ejemplo, en árabe), como se explica aquí: blogs.msdn.com/oldnewthing/archive/2004/03/09/86555.aspx
    2009-07-09 10: 07: 59Z
  2. la solución numberFormatter es probablemente solo ligeramente mejor que capturar la excepción NumberFormatException. Sospecho que la mejor manera es usar regex uno.
    2009-07-09 11: 22: 25Z
  3. Tenga en cuenta que el . en su expresión regular coincidirá con cualquier carácter, no solo con el carácter separador decimal.
    2009-07-11 08: 16: 11Z
  4. + 1 para realizar el gasto de try /catch. Este es realmente un enfoque horrible para usar a largo plazo para un uso repetido, pero realmente estamos atascados con eso en Java.
    2011-09-06 15: 20: 25Z
  5. Tenga en cuenta que no existen elementos como los "números latinos" y que los números del 0 al 9 son de hecho números arábigos. Las personas probablemente son familiares con los números romanos, que fueron utilizados por personas que hablaban latín, en la forma I, II, III, IV, V, VI, etc. en.wikipedia.org/wiki/Arabic_numerals ; en.wikipedia.org/wiki/Roman_numerals
    2016-03-05 00: 26: 40Z

si estás en Android, debes usar:

 
android.text.TextUtils.isDigitsOnly(CharSequence str)

documentación se puede encontrar aquí

hazlo simple . Casi todo el mundo puede "reprogramar" (lo mismo).

    
141
2013-11-22 21: 44: 16Z
  1. Esto no funcionará para 123.456; (
    2014-02-07 00: 41: 35Z
  2. @ kape123 :) seguro que" 123.456 "no contiene dígitos.
    2014-11-14 18: 01: 31Z
  3. Nota: esto da como resultado NPE para entrada nula. Además, no funciona con números negativos o decimales.
    2014-12-19 17: 36: 43Z
  4. ¡Me gusta! Creo que esto es absolutamente para los dígitos. No para ., -
    2016-09-13 03: 29: 20Z
  5. Esto es justo lo que estaba buscando. Algo simple para verificar solo los dígitos 0-9. Puse un filtro en la declaración de mi EditText, pero en caso de que se modifique o reemplace en el camino, también es bueno tener una simple verificación programática.
    2018-06-26 18: 59: 52Z

Como @CraigTP mencionó en su excelente respuesta, también tengo problemas de rendimiento en el uso de Excepciones para probar si la cadena es numérica o no. Así que termino dividiendo la cadena y uso java.lang.Character.isDigit().

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

Según Javadoc , Character.isDigit(char) reconocerá correctamente los dígitos no latinos. En cuanto al rendimiento, creo que un simple número de comparaciones con N donde N es el número de caracteres en la cadena sería más eficiente desde el punto de vista computacional que hacer una comparación de expresiones regulares.

ACTUALIZACIÓN: Como señaló Jean-François Corbett en el comentario, el código anterior solo validaría los enteros positivos, que cubren la mayoría de mi caso de uso. A continuación se muestra el código actualizado que valida correctamente los números decimales de acuerdo con la configuración regional predeterminada utilizada en su sistema, asumiendo que el separador decimal solo ocurre una vez en la cadena.

 
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;
}
    
116
2012-03-13 13: 32: 17Z
  1. ¿El separador decimal tampoco hará que esto falle?
    2012-01-06 08: 55: 04Z
  2. @ Jean-FrançoisCorbett: Buen punto, he actualizado el código con uno más nuevo que acepta separadores de decimales.
    2012-03-13 13: 33: 56Z
  3. ¿Signo -ve falla esta función?
    2013-05-29 14: 14: 03Z
  4. Creo que esta debería ser la respuesta aceptada porque es la solución más sencilla. Usar una excepción o una expresión regular son muy pesados ​​para comprobar si una cadena es numérica. ¡Iterar sobre los personajes es agradable y simple!
    2013-12-01 10: 22: 30Z
  5. Llamar al toCharArray() creará una copia de la matriz en el objeto String porque las Strings son inmutables. Probablemente sea más rápido usar el método charAt(int index) en el objeto String directamente.
    2014-10-08 22: 31: 35Z

Expresiones lambda de Java 8.

 
String someString = "123123";
boolean isNumeric = someString.chars().allMatch( Character::isDigit );
    
91
2016-04-28 19: 56: 00Z
  1. También puede usar una referencia de método: someString.chars (). allMatch (Character :: isDigit)
    2016-02-08 17: 35: 56Z
  2. Bien, pero aún así está reinventando la rueda como casi todas las "soluciones" aquí. Además, falla en 'null' (como en casi todos los demás).
    2016-03-24 10: 03: 03Z
  3. Esta respuesta es concisa, simple y legible. Casi se puede leer como en inglés: "los caracteres coinciden todos los dígitos". No requiere bibliotecas de terceros. No utiliza excepciones en casos no excepcionales. Esto debería convertirse en la respuesta aceptada.
    2016-04-28 20: 02: 15Z
  4. ¿Qué producirá para "-1"?
    2016-06-28 13: 32: 52Z
  5. @ Adrian aquí es un punto de referencia: gist. github.com/maxmalysh/8f656be2843b7c35849a2eae2683df0e . 9ms para una cadena de 1 millón de caracteres. 169 ms para una cadena de longitud de caracteres de 5k es algo demasiado fuera de lugar.
    2017-02-16 17: 55: 43Z

La biblioteca de guayabas de Google proporciona un buen método auxiliar para hacer esto: Ints.tryParse. Lo usa como Integer.parseInt pero devuelve null en lugar de lanzar una excepción si la cadena no se analiza a un entero válido. Tenga en cuenta que devuelve Integer, no int, por lo que debe convertirlo /autobox de nuevo a int.

Ejemplo:

 
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

Sin embargo, a partir de la versión actual - Guava r11 - todavía está marcado como @Beta.

No lo he evaluado. Mirando el código fuente, hay una sobrecarga de mucha comprobación de cordura, pero al final usan Character.digit(string.charAt(idx)), similar, pero ligeramente diferente a, la respuesta de @Ibrahim arriba. No hay una sobrecarga de manejo de excepción bajo las coberturas en su implementación.

    
43
2012-01-29 20: 13: 07Z
  1. Tenga cuidado de que esto arroje NPE en caso de que el argumento sea nulo.
    2019-06-18 11: 28: 58Z

No utilice excepciones para validar sus valores. Use Utils libs como apache NumberUtils:

 
NumberUtils.isNumber(myStringValue);

Editar :

Tenga en cuenta que, si su cadena comienza con un 0, NumberUtils interpretará su valor como hexadecimal.

 
NumberUtils.isNumber("07") //true
NumberUtils.isNumber("08") //false
    
27
2018-04-20 08: 04: 52Z
  1. La respuesta aceptada, tres años antes, ya cubrió Number.isNumber().
    2016-04-28 19: 29: 22Z
  2. No lo creo. Se actualizó o se cambió la respuesta aceptada. Recuerdo que la respuesta aceptada no cubría NumberUtils, por eso agregué mi respuesta. Pero gracias por el comentario
    2016-04-29 07: 23: 27Z
  3. @ Goot - El historial de la respuesta aceptada muestra que Number.isNumber() estuvo presente desde la primera versión de la respuesta, con fecha 24 de septiembre de 2014 a las 17:01.
    2017-02-16 18: 32: 35Z
  4. @ Goot, esto es bastante bueno ya que también cubre la verificación del valor decimal, a diferencia de StringUtils.
    2018-02-02 06: 20: 10Z

¿Por qué todos están presionando para obtener soluciones de excepción /expresión regular?

Si bien puedo entender que la mayoría de las personas están bien con el uso de try /catch, si quieres hacerlo con frecuencia ... puede ser extremadamente agotador.

Lo que hice aquí fue tomar la expresión regular, los métodos parseNumber () y el método de búsqueda matricial para ver cuál era el más eficiente. Esta vez, solo miré los números enteros.

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

Los resultados en velocidad que obtuve fueron:

 
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

Descargo de responsabilidad: no estoy diciendo que estos métodos estén 100% optimizados, son solo para la demostración de los datos

Las excepciones se obtienen si y solo si el número es de 4 caracteres o menos, y cada cadena es siempre un número ... en cuyo caso, ¿por qué incluso tener un cheque?

En resumen, es extremadamente doloroso si te topas con números no válidos con frecuencia con el try /catch, lo cual tiene sentido. Una regla importante que siempre sigo es NUNCA use try /catch para el flujo del programa . Este es un ejemplo de por qué.

Curiosamente, el simple if char < 0 || > 9 fue extremadamente simple de escribir, fácil de recordar (y debería funcionar en varios idiomas) y gana casi todos los escenarios de prueba.

El único inconveniente es que supongo que Integer.parseInt () podría manejar números que no sean ASCII, mientras que el método de búsqueda de matrices no.


Para aquellos que se preguntan por qué dije que es fácil recordar la matriz de caracteres uno, si sabes que no hay signos negativos, puedes salirte con algo condensado como esto:

 
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;

Por último, como nota final, sentí curiosidad por el operador del proyecto en el ejemplo aceptado con todos los votos arriba. Añadiendo en la asignación de

 
double d = Double.parseDouble(...)

no solo es inútil ya que ni siquiera usa el valor, sino que desperdicia el tiempo de procesamiento y aumenta el tiempo de ejecución en unos pocos nanosegundos (lo que llevó a un aumento de 100-200 ms en las pruebas). No veo por qué alguien haría eso, ya que en realidad es un trabajo adicional para reducir el rendimiento.

Usted pensaría que se optimizaría ... aunque quizás debería revisar el código de bytes y ver qué está haciendo el compilador. Eso no explica por qué siempre se mostró más largo para mí, aunque si de alguna manera está optimizado ... por lo tanto, me pregunto qué está pasando. Como nota: más largo, me refiero a ejecutar la prueba para 10000000 iteraciones, y ejecutar ese programa varias veces (10x +) siempre mostró que era más lento.

EDITAR: se actualizó una prueba para Character.isDigit ()

    
21
2015-03-29 16: 18: 09Z
  1. ¿No compila esto una nueva expresión regular cada vez? Eso no parece muy eficiente.
    2015-06-11 16: 26: 49Z
  2. @ SamuelEdwinWard Esa es la razón completa que hice esta publicación ... el ejemplo de expresiones regulares usó las respuestas proporcionadas por otras personas y mostró cuán ineficiente es. Incluso si intenta una expresión regular con la precompilación previa y solo la utiliza, las diferencias de tiempo son: 2587 ms para la expresión regular que publiqué de otras personas proporcionadas, 950 ms cuando se compilaron antes de tiempo, 144 ms cuando se hace como un matriz numérica (para 1 mil iteraciones de la misma cadena). Compilar con anticipación obviamente ayudaría, pero lamentablemente todavía es bastante inferior a la forma de la matriz ... a menos que haya una optimización insana que no conozco.
    2015-06-12 14: 26: 56Z
 
public static boolean isNumeric(String str)
{
    return str.matches("-?\\d+(.\\d+)?");
}

La expresión regular de CraigTP (que se muestra arriba) produce algunos falsos positivos. P.ej. "23y4" se contará como un número porque '.' coincide con cualquier carácter que no sea el punto decimal.

También rechazará cualquier número con un '+' inicial

Una alternativa que evita estos dos problemas menores es

 
public static boolean isNumeric(String str)
{
    return str.matches("[+-]?\\d*(\\.\\d+)?");
}
    
18
2011-11-22 21: 22: 07Z
  1. esto devolverá true para un solo más "+" o menos "-", y false para "0."
    2011-09-17 17: 16: 43Z
  2. Buena captura en el único más o menos. Es "0". ¿Un número válido?
    2011-09-18 08: 39: 33Z
  3. "0." es válido para Double.parseDouble() y es un literal válido según el JLS ( §3.10.2 )!
    2011-09-18 15: 49: 17Z
  4. La creación de expresiones regulares también es costosa. La expresión regular debe crearse una vez y reutilizarse
    2014-02-03 18: 17: 11Z
  5. La respuesta no está completa. "21a12".matches("-?\\d+(.\\d+)?") devuelve verdadero !!!
    2016-01-05 12: 33: 31Z

Puede usar NumberFormat#parse :

 
try
{
     NumberFormat.getInstance().parse(value);
}
catch(ParseException e)
{
    // Not a number.
}
    
12
2015-04-06 01: 25: 13Z
  1. Se ofreció una edición: faltaba .getInstance (). +1 ya que esta fue la respuesta que obtuve al encontrar esta pregunta.
    2012-04-10 12: 45: 32Z
  2. Costoso si se usa extensivamente
    2014-02-03 18: 17: 42Z
  3. También pasará si hay caracteres de basura al final de value.
    2014-02-26 03: 11: 00Z
  4. Crearía un problema de sonar si no registra la excepción
    2018-04-12 09: 54: 15Z
  5. Esto funcionó para el formato de número 0x0001 donde Double.parseDouble no estaba funcionando. +1
    2018-08-16 17: 41: 48Z

Podemos intentar reemplazar todos los números de la cadena dada con (""), es decir, espacio en blanco y si después de eso la longitud de la cadena es cero, podemos decir que la cadena dada solo contiene números. [Si encuentra útil esta respuesta, por favor considere votarla] Ejemplo:

 
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 point
        System.out.println(str);

        return str.replaceAll("[0-9]","").length() == 0;
    }
    
12
2019-04-07 06: 32: 28Z
  1. Entonces "" es un número, pero "3.14" y "-1" no lo son.
    2019-03-28 12: 48: 56Z

Si usa java para desarrollar la aplicación de Android, puede usar Función TextUtils.isDigitsOnly .

    
11
2014-02-25 13: 06: 35Z

Aquí estaba mi respuesta al problema.

Un método de captura de conveniencia que puede usar para analizar cualquier cadena con cualquier tipo de analizador: isParsable(Object parser, String str). El analizador puede ser un Class o un object. Esto también le permitirá usar los analizadores personalizados que ha escrito y debería funcionar para cada escenario, por ejemplo:

 
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");

Aquí está mi código completo con descripciones de métodos.

 
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;
    }
}
    
8
2014-03-29 01: 06: 04Z
  1. + 1 para una exageración absoluta
    2012-02-10 12: 23: 57Z

Paraemparejar solo enteros de base diez positivos, que contienen solo dígitos ASCII, use:

 
public static boolean isNumeric(String maybeNumeric) {
    return maybeNumeric != null && maybeNumeric.matches("[0-9]+");
}
    
5
2014-08-14 13: 02: 23Z

Un enfoque de buen desempeño que evita el intento de captura y el manejo de números negativos y notación científica.

 
Pattern PATTERN = Pattern.compile( "^(-?0|-?[1-9]\\d*)(\\.\\d+)?(E\\d+)?$" );

public static boolean isNumeric( String value ) 
{
    return value != null && PATTERN.matcher( value ).matches();
}
    
5
2015-04-08 14: 42: 16Z

Aquí está mi clase para verificar si una cadena es numérica. También corrige cadenas numéricas:

Características:

  1. Elimina los ceros innecesarios ["12.0000000" - > "12"]
  2. Elimina los ceros innecesarios ["12.0580000" - > "12.058"]
  3. Elimina los caracteres no numéricos ["12.00sdfsdf00" - > "12"]
  4. Maneja valores de cadena negativos ["-12,020000" - > "-12.02"]
  5. Elimina varios puntos ["-12.0.20.000" - > "-12.02"]
  6. No hay bibliotecas adicionales, solo Java estándar

Aquí tienes ...

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

}
    
5
2015-04-28 06: 15: 54Z
  

Regex Matching

Este es otro ejemplo de la expresión regular "CraigTP" actualizada con más validaciones.

 
public static boolean isNumeric(String str)
{
    return str.matches("^(?:(?:\\-{1})?\\d+(?:\\.{1}\\d+)?)$");
}
  1. Solo se permite un signo negativo - y debe estar al principio.
  2. Después del signo negativo debe haber un dígito.
  3. Sólo se permite un signo decimal . .
  4. Después del signo decimal debe haber un dígito.
  

Regex Test

 
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
    
5
2015-06-15 06: 10: 35Z

Las excepciones son caras, pero en este caso el RegEx toma mucho más tiempo. El código a continuación muestra una prueba simple de dos funciones: una con excepciones y la otra con expresiones regulares. En mi máquina, la versión RegEx es 10 veces más lenta que la excepción.

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

}

}
    
5
2015-06-18 13: 52: 33Z
  1. En general, creo que este tipo de código se usaría para verificar cosas como la entrada escrita. En ese caso, la velocidad no es una consideración y hacer algo tan feo como lanzar una excepción para verificar el número o no número es incorrecto.
    2015-08-07 15: 03: 23Z
  2. Tal vez no. La entrada escrita se comprueba generalmente por el componente de la interfaz de usuario, donde los errores se pueden mostrar inmediatamente antes de enviar el valor. Podría ser más común validar cadenas de archivos de texto de entrada grandes, donde el rendimiento es importante. El objetivo en mi respuesta aquí es abordar la declaración de "las excepciones son lentas" en la respuesta aceptada. El regex complejo es mucho más caro. Y no hay ninguna "tirada fea" en mi código, solo una forma más rápida de detectar violaciones Con un método de verificación de primero, luego de cálculo, se realizan dos pases a través de la entrada: uno para verificar y luego otro para convertir.
    2015-08-08 15: 52: 56Z

//por favor revise el siguiente código

 
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;
}
    
4
2016-09-16 12: 57: 17Z
  1. La pregunta dice "numérico" que podría incluir valores no enteros.
    2016-09-16 13: 18: 18Z
 
// 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;
    }
}
    
3
2015-04-06 01: 32: 17Z

Este es un ejemplo simple para esta comprobación:

 
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;
}
    
3
2015-04-06 01: 35: 04Z

Puedes usar el objeto java.util.Scanner.

 
public static boolean isNumeric(String inputData) {
      Scanner sc = new Scanner(inputData);
      return sc.hasNextInt();
    }
    
3
2015-08-19 07: 52: 20Z

He modificado la solución de CraigTP para aceptar la notación científica y los separadores de puntos y comas también como separadores decimales

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

ejemplo

 
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
    
2
2013-12-05 14: 40: 17Z

Por eso me gusta el enfoque Try * en .NET. Además del método Parse tradicional que es como el de Java, también tiene un método TryParse. No soy bueno en la sintaxis de Java (¿de parámetros?), Así que trate lo siguiente como una especie de pseudocódigo. Sin embargo, debería aclarar el concepto.

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

Uso:

 
int num;
if (parseInteger("23", out num)) {
    // Do something with num.
}
    
2
2014-11-06 12: 22: 17Z
  1. sip, no hay "parámetros de salida" en Java y dado que el envoltorio Integer es inmutable (por lo tanto, no se puede usar como una referencia válida para almacenar la salida), el idiomático sensible La opción sería devolver un objeto Integer que podría ser nulo si el análisis fallara. Una opción más fea podría ser pasar un int [1] como parámetro de salida.
    2009-07-09 10: 37: 19Z
  2. Sí, recuerdo una discusión sobre por qué Java no tiene parámetros de salida. pero devolver un Integer (como nulo, si es necesario) también estaría bien, supongo, aunque no conozco el rendimiento de Java con respecto al boxeo /desempaquetado.
    2009-07-09 11: 19: 21Z
  3. Me gusta C # tanto como el siguiente tipo, pero no sirve de nada agregar un fragmento de código .NET C # para una pregunta de Java cuando las características no existen en Java
    2015-01-28 10: 15: 48Z
  4. Crearía un problema de sonar si no registra la excepción
    2018-04-12 09: 54: 57Z

Analícelo (es decir, con Integer#parseInt ) y simplemente detecte la excepción. =)

Para aclarar: la función parseInt comprueba si puede analizar el número en cualquier caso (obviamente) y si desea analizarlo de todos modos, no va a tener ningún impacto en el rendimiento al realizar el análisis.

Si no desea analizarlo (o analizarlo muy, muy raramente), es posible que desee hacerlo de forma diferente, por supuesto.

    
2
2015-04-06 01: 15: 37Z
  1. Costoso si se usa extensivamente
    2014-02-03 18: 18: 06Z
  2. Crearía un problema de sonar si no registra la excepción
    2018-04-12 09: 54: 03Z
  3. Double.parseDouble
    2018-12-04 15: 01: 29Z

Puede usar NumberUtils.isCreatable () desde Apache Commons Lang .

Dado que NumberUtils.isNumber quedará en desuso en 4.0, entonces use NumberUtils.isCreatable () en su lugar.

    
2
2016-11-13 13: 40: 22Z

Aquí hay dos métodos que podrían funcionar. (Sin usar excepciones). Nota: Java es un valor de paso por valor predeterminado y el valor de una cadena es la dirección de los datos del objeto de la cadena. Entonces, cuando estás haciendo

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

Ha cambiado el valor de entrada para que no tenga espacios. Puedes eliminar esa línea si quieres.

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

Aquí hay otro método en caso de que quiera permitir flotantes Este método supuestamente permite que los números en la forma pasen 1,123,123,123,123,123.123 Lo acabo de hacer y creo que necesita más pruebas para garantizar que funcione.

 
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;
}
    
1
2013-04-20 11: 15: 26Z
  1. ¿Qué sucede si el número contiene comas o puntos decimales?
    2013-04-19 18: 51: 39Z
  2. Oh, buena pregunta. Supongo que este solo funciona con enteros de tipo normal. El método se creó inicialmente para filtrar los números de teléfono de entrada y los números de conteo.
    2013-04-19 22: 01: 19Z

Puede usar BigDecimal si la cadena puede contener decimales:

 
try {
    new java.math.BigInteger(testString);
} catch(NumberFormatException e) {
    throw new RuntimeException("Not a valid number");
}
    
1
2014-03-29 01: 06: 57Z
  1. Bienvenido a stackoverflow. En general, es mejor evitar resucitar hilos viejos a menos que la respuesta agregue algo significativamente diferente al hilo. Si bien es válido, ese enfoque ya se mencionó en la respuesta aceptada.
    2012-04-06 21: 28: 57Z
  2. Crearía un problema de sonar si no registra la excepción
    2018-04-12 09: 55: 51Z

Secuencia Java 8, expresión lambda, interfaz funcional

Todos los casos manejados ( cadena nula, cadena vacía, etc. )

 
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();
    
1
2016-12-20 10: 36: 55Z

Esta es la forma más rápida que conozco para verificar si la cadena es número o no:

 
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';
}
    
1
2017-04-09 12: 10: 37Z
fuente colocada aquí