2010-08-22 22 views

Respuesta

36

El enfoque común sería la de comprobar que con una expresión regular como también sugiere el interior de la documentación Double.valueOf(String).

La expresión regular proporcionada allí (o incluida a continuación) debe cubrir todos los casos de punto flotante válidos, por lo que no necesita jugar con ella, ya que eventualmente se perderá algunos de los puntos más finos.

Si no quiere hacer eso, try catch sigue siendo una opción.

La expresión regular sugerido por el JavaDoc se incluye a continuación:

final String Digits  = "(\\p{Digit}+)"; 
final String HexDigits = "(\\p{XDigit}+)"; 
// an exponent is 'e' or 'E' followed by an optionally 
// signed decimal integer. 
final String Exp  = "[eE][+-]?"+Digits; 
final String fpRegex = 
    ("[\\x00-\\x20]*"+ // Optional leading "whitespace" 
    "[+-]?(" +   // Optional sign character 
    "NaN|" +   // "NaN" string 
    "Infinity|" +  // "Infinity" string 

    // A decimal floating-point string representing a finite positive 
    // number without a leading sign has at most five basic pieces: 
    // Digits . Digits ExponentPart FloatTypeSuffix 
    // 
    // Since this method allows integer-only strings as input 
    // in addition to strings of floating-point literals, the 
    // two sub-patterns below are simplifications of the grammar 
    // productions from the Java Language Specification, 2nd 
    // edition, section 3.10.2. 

    // Digits ._opt Digits_opt ExponentPart_opt FloatTypeSuffix_opt 
    "((("+Digits+"(\\.)?("+Digits+"?)("+Exp+")?)|"+ 

    // . Digits ExponentPart_opt FloatTypeSuffix_opt 
    "(\\.("+Digits+")("+Exp+")?)|"+ 

    // Hexadecimal strings 
    "((" + 
    // 0[xX] HexDigits ._opt BinaryExponent FloatTypeSuffix_opt 
    "(0[xX]" + HexDigits + "(\\.)?)|" + 

    // 0[xX] HexDigits_opt . HexDigits BinaryExponent FloatTypeSuffix_opt 
    "(0[xX]" + HexDigits + "?(\\.)" + HexDigits + ")" + 

    ")[pP][+-]?" + Digits + "))" + 
    "[fFdD]?))" + 
    "[\\x00-\\x20]*");// Optional trailing "whitespace" 

if (Pattern.matches(fpRegex, myString)){ 
    Double.valueOf(myString); // Will not throw NumberFormatException 
} else { 
    // Perform suitable alternative action 
} 
+0

+1 - Mucho mejor que atrapar una excepción (mi respuesta coja ...) – Starkey

+0

¿cómo se hace esto exactamente? –

+2

@Louis Rhys: hay un ejemplo de código en el enlace de documentación en la respuesta. – Starkey

43

Siempre puede ajustar Double.parseDouble() en un bloque try catch.

try 
{ 
    Double.parseDouble(number); 
} 
catch(NumberFormatException e) 
{ 
    //not a double 
} 
+7

Este sería mi método preferido porque su garantía para obtener exactamente el mismo comportamiento que el análisis. Es muy fácil con una expresión regular personalizada pasar por alto las mayúsculas y minúsculas. –

+2

Esto es bueno EXCEPTO si escribe un número seguido de un espacio, no lo capta. – giant91

+2

@ giant91 - simplemente recorte el número: 'number.trim()'. – 26hmkk

8

Algo parecido a continuación debería ser suficiente: -

String decimalPattern = "([0-9]*)\\.([0-9]*)"; 
String number="20.00"; 
boolean match = Pattern.matches(decimalPattern, number); 
System.out.println(match); //if true then decimal else not 
+2

en realidad es más complicado que eso. ver la respuesta de johannes wachter –

+1

Entendido. El enlace que Wachter proporcionó es útil de hecho. – CoolBeans

+0

Hola, esto es más apropiado para dobles: String doublePattern = "([0-9]. *) \\. ([0-9]. *)"; – voodoo98

48

Apache, como de costumbre, tiene una buena respuesta de Apache Commons-Lang en forma de org.apache.commons.lang3.math.NumberUtils.isNumber(String)

Maneja nulos, no try/catch bloque requerido.

+0

¿Apache se envía con el JDK normal? –

+5

No. Puede encontrar las bibliotecas de Apache Commons aquí. http://commons.apache.org/. Se recomienda encarecidamente que los use en lugar de escribir código personalizado siempre que pueda. –

+1

¿Identifica esto números decimales? – TechCrunch

6

Todas las respuestas son correctas, dependiendo de cuán académico desee ser. Si desea seguir las especificaciones Java con precisión, utilice la siguiente:

private static final Pattern DOUBLE_PATTERN = Pattern.compile(
    "[\\x00-\\x20]*[+-]?(NaN|Infinity|((((\\p{Digit}+)(\\.)?((\\p{Digit}+)?)" + 
    "([eE][+-]?(\\p{Digit}+))?)|(\\.((\\p{Digit}+))([eE][+-]?(\\p{Digit}+))?)|" + 
    "(((0[xX](\\p{XDigit}+)(\\.)?)|(0[xX](\\p{XDigit}+)?(\\.)(\\p{XDigit}+)))" + 
    "[pP][+-]?(\\p{Digit}+)))[fFdD]?))[\\x00-\\x20]*"); 

public static boolean isFloat(String s) 
{ 
    return DOUBLE_PATTERN.matcher(s).matches(); 
} 

Este código se basa en los JavaDocs en Double.

6

La biblioteca de guayaba de Google proporciona un buen método de ayuda para hacer esto: Doubles.tryParse(String). Lo usa como Double.parseDouble pero devuelve null en lugar de arrojar una excepción si la cadena no se convierte en un doble.

Cuestiones relacionadas