2010-08-22 3 views

Répondre

36

L'approche commune serait de le vérifier avec une expression régulière comme il est suggéré aussi à l'intérieur de la documentation Double.valueOf(String). L'expression rationnelle fournie ici (ou incluse ci-dessous) devrait couvrir tous les cas de virgule flottante valides, donc vous n'avez pas besoin de jouer avec, car vous finirez par passer à côté de certains des points plus fins. Si vous ne souhaitez pas faire cela, try catch est toujours une option.

Le regexp suggéré par le JavaDoc est inclus ci-dessous:

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 - Beaucoup mieux que d'attraper une exception (ma réponse boiteuse ...) – Starkey

+0

comment fait-on exactement? –

+2

@Louis Rhys - Il y a un exemple de code dans le lien de la documentation dans la réponse. – Starkey

43

Vous pouvez toujours placer Double.parseDouble() dans un bloc try catch.

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

Ce serait ma méthode préférée parce que votre garantie d'obtenir exactement le même comportement que l'analyse. Il est très facile avec une expression régulière personnalisée d'ignorer les cas de bordure. –

+2

Cela est bon, SAUF si vous tapez un nombre suivi d'un espace, il ne l'attrape pas. – giant91

+2

@ giant91 - il suffit de rogner le nombre: 'number.trim()'. – 26hmkk

8

Quelque chose comme ci-dessous devrait suffire: -

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 fait c'est plus compliqué que ça. voir la réponse de johannes wachter –

+1

Got it. Le lien que Wachter a fourni est vraiment utile. – CoolBeans

+0

Salut, c'est plus approprié pour les doubles: String doublePattern = "([0-9]. *) \\. ([0-9]. *)"; – voodoo98

48

Apache, comme d'habitude, a une bonne réponse de Apache Commons-Lang sous forme de org.apache.commons.lang3.math.NumberUtils.isNumber(String)

Les poignées sont nulles, aucune try/catch n'est requise.

+0

Apache est-il livré avec le JDK normal? –

+5

Non. Vous pouvez trouver les bibliothèques Apache Commons ici. http://commons.apache.org/ Nous vous recommandons vivement de les utiliser plutôt que d'écrire du code personnalisé chaque fois que vous le pouvez. –

+1

Est-ce que cela identifie les nombres décimaux? – TechCrunch

6

Toutes les réponses sont OK, selon la façon dont vous voulez être académique. Si vous souhaitez suivre les spécifications Java avec précision, utilisez les touches suivantes:

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

Ce code est basé sur les JavaDocs à Double.

6

La bibliothèque Guava de Google fournit une méthode d'aide intéressante pour ce faire: Doubles.tryParse(String). Vous l'utilisez comme Double.parseDouble mais il renvoie null plutôt que de lancer une exception si la chaîne n'analyse pas un double.

Questions connexes