Comment vérifier si une Chaîne est numérique en Java

Comment vérifieriez-vous si une chaîne était un nombre avant de l'analyser?

719
demandé sur Boann 2009-07-09 13:49:47

30 réponses

Avec Apache Commons Lang 3.5 et au-dessus: NumberUtils.isCreatable ou StringUtils.isNumeric.

Avec Apache Commons Lang 3.4 et ci-dessous: NumberUtils.isNumber ou StringUtils.isNumeric.

Vous pouvez également utiliser StringUtils.isNumericSpace qui renvoie true pour les chaînes vides et ignore les espaces internes de la chaîne. (Les javadocs liés contiennent des exemples détaillés pour chaque méthode.)

579
répondu palacsint 2017-01-16 13:33:11

Ceci est généralement fait avec une simple fonction définie par l'utilisateur (c'est à dire Rouler "isNumeric" de la fonction).

Quelque Chose comme:

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

Cependant, si vous appelez beaucoup cette fonction et que vous vous attendez à ce que de nombreuses vérifications échouent parce que vous n'êtes pas un nombre, les performances de ce mécanisme ne seront pas excellentes, car vous comptez sur des exceptions pour chaque échec, ce qui est une opération assez coûteuse.

Une autre approche peut être d'utiliser un expression pour vérifier la validité d'un nombre:

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

Soyez prudent avec le mécanisme RegEx ci-dessus, car il échouera si vous utilisez des chiffres non arabes (c'est-à-dire des chiffres autres que 0 à 9). C'est parce que la partie "\d" De L'expression rationnelle ne correspondra qu'à [0-9] et n'est effectivement pas au courant numériquement international. (Merci à OregonGhost pour le souligner!)

Ou même une autre alternative consiste à utiliser java intégré de Java.texte.Objet NumberFormat pour voir si, après l'analyse de la chaîne de l'analyseur est la position à la fin de la chaîne. Si c'est le cas, nous pouvons supposer que la chaîne entière est numérique:

public static boolean isNumeric(String str)
{
  NumberFormat formatter = NumberFormat.getInstance();
  ParsePosition pos = new ParsePosition(0);
  formatter.parse(str, pos);
  return str.length() == pos.getIndex();
}
802
répondu CraigTP 2018-04-02 11:26:03

Si vous êtes sur android, alors vous devriez utiliser:

android.text.TextUtils.isDigitsOnly(CharSequence str)

La Documentation peut être trouvée ici

reste simple. la plupart du temps tout le monde peut "re-programmer" (la même chose).

132
répondu Ahmed Alejo 2013-11-22 21:44:16

Comme @CraigTP l'avait mentionné dans son excellente réponse, j'ai aussi des problèmes de performance similaires sur l'utilisation D'Exceptions pour tester si la chaîne est numérique ou non. Donc, je finis par diviser la chaîne et utiliser java.lang.Character.isDigit().

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

Selon le Javadoc, Character.isDigit(char) reconnaîtra correctement les chiffres non latins. Du point de vue des performances, je pense qu'un simple N nombre de comparaisons où N est le nombre de caractères dans la chaîne serait plus efficace sur le plan du calcul que de faire une regex correspondre.

UPDATE: comme l'a souligné Jean-François Corbett dans le commentaire, le code ci-dessus ne validerait que des entiers positifs, ce qui couvre la majorité de mon cas d'utilisation. Vous trouverez ci-dessous le code mis à jour qui valide correctement les nombres décimaux en fonction des paramètres régionaux par défaut utilisés dans votre système, en supposant que le séparateur décimal ne se produit qu'une seule fois dans la chaîne.

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;
}
109
répondu Ibrahim Arief 2012-03-13 13:32:17

Java 8 expressions lambda.

String someString = "123123";
boolean isNumeric = someString.chars().allMatch( Character::isDigit );
72
répondu Max Malysh 2016-04-28 19:56:00

La bibliothèque goyave de Google fournit une méthode d'aide intéressante pour faire ceci: Ints.tryParse. Vous l'utilisez comme Integer.parseInt mais il renvoie null plutôt que de lancer une Exception si la chaîne n'analyse pas un entier valide. Notez qu'il renvoie Integer, pas int, donc vous devez le convertir / autobox en int.

Exemple:

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

Cependant, à partir de la version actuelle -- Guava r11 -- il est toujours marqué @ Beta.

Je ne l'ai pas comparé. En regardant le code source il y a quelques frais généraux d'un beaucoup de vérifications, mais à la fin ils utilisent Character.digit(string.charAt(idx)), similaire, mais légèrement différente de la réponse de @Ibrahim ci-dessus. Il n'y a pas d'exception à la gestion des frais généraux sous les couvertures dans leur mise en œuvre.

42
répondu quux00 2012-01-29 20:13:07

N'utilisez pas D'Exceptions pour valider vos valeurs. Utilisez les bibliothèques Util à la place comme Apache NumberUtils:

NumberUtils.isNumber(myStringValue);

Modifier :

Veuillez noter que, si votre chaîne commence par un 0, NumberUtils interprétera votre valeur comme hexadécimale.

NumberUtils.isNumber("07") //true
NumberUtils.isNumber("08") //false
27
répondu Goot 2018-04-20 08:04:52

Pourquoi tout le monde pousse-t-il pour des solutions d'exception / regex?

Bien que je puisse comprendre que la plupart des gens utilisent try/catch, si vous voulez le faire fréquemment... il peut être extrêmement pénible.

Ce que j'ai fait ici était de prendre la regex, les méthodes parseNumber() et la méthode de recherche de tableau pour voir laquelle était la plus efficace. Cette fois, je n'ai regardé que des nombres entiers.

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

Les résultats en vitesse que j'ai obtenus étaient:

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

Disclaimer: je ne suis pas affirmant que ces méthodes sont 100% optimisées, elles sont juste pour la démonstration des données

Exceptions gagné si et seulement si le nombre est de 4 caractères ou moins, et chaque chaîne est toujours un certain nombre... dans ce cas, pourquoi même avoir un chèque?

En bref, il est extrêmement douloureux si vous rencontrez fréquemment des numéros invalides avec l'essai / capture, ce qui est logique. Une règle importante que je suis toujours est Ne jamais utiliser try / catch pour le flux de programme . C'est un exemple pourquoi.

Fait intéressant, le simple if char 9 était extrêmement simple à écrire, facile à retenir (et devrait fonctionner dans plusieurs langues) et gagne presque tous les scénarios de test.

Le seul inconvénient est que je devine entier.parseInt () peut gérer des nombres non ASCII, contrairement à la méthode de recherche de tableau.


Pour ceux qui se demandent pourquoi j'ai dit qu'il est facile de se souvenir du tableau de caractères one, Si vous savez qu'il n'y a pas de signes négatifs, vous pouvez facilement vous en sortir quelque chose de condensé comme ceci:

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;

Enfin, en guise de note finale, j'étais curieux de connaître l'opérateur d'assignation dans l'exemple accepté avec tous les votes. Ajouter dans l'affectation de

double d = Double.parseDouble(...)

N'est pas seulement inutile puisque vous n'utilisez même pas la valeur, mais cela gaspille du temps de traitement et augmente le temps d'exécution de quelques nanosecondes (ce qui a conduit à une augmentation de 100-200 ms dans les tests). Je ne vois pas pourquoi quelqu'un ferait cela car il s'agit en fait d'un travail supplémentaire à réduire performance.

On pourrait penser que ce serait optimisé... bien que je devrais peut-être vérifier le bytecode et voir ce que fait le compilateur. Cela n'explique pas pourquoi il est toujours apparu comme plus long pour moi si c'est en quelque sorte optimisé... donc je me demande ce qu'il se passe. Comme une note: par Plus longue, je veux dire exécuter le test pour 10000000 itérations, et exécuter ce programme plusieurs fois (10x+) a toujours montré qu'il était plus lent.

EDIT: mise à jour d'un test pour Caractère.appel isdigit()

19
répondu Water 2015-03-29 16:18:09
public static boolean isNumeric(String str)
{
    return str.matches("-?\\d+(.\\d+)?");
}

L'expression régulière de CraigTP (ci-dessus) produit des faux positifs. Par exemple, "23y4" sera compté comme un nombre parce que".'correspond à n'importe quel caractère qui n'est pas le point décimal.

En outre, il rejettera n'importe quel nombre avec un premier ' + '

Une alternative qui évite ces deux problèmes mineurs est

public static boolean isNumeric(String str)
{
    return str.matches("[+-]?\\d*(\\.\\d+)?");
}
17
répondu user872985 2011-11-22 21:22:07

Vous pouvez utiliser NumberFormat#parse:

try
{
     NumberFormat.getInstance().parse(value);
}
catch(ParseException e)
{
    // Not a number.
}
12
répondu Artem Barger 2015-04-06 01:25:13

Si vous utilisez java pour développer une application Android, vous pouvez utiliser TextUtils.fonction isDigitsOnly .

11
répondu Eric Guo 2014-02-25 13:06:35

Voici ma réponse au problème.

Catch toutes les commodités méthode que vous pouvez utiliser pour analyser une Chaîne avec n'importe quel type d'analyseur: isParsable(Object parser, String str). L'analyseur peut être un Class ou object. Cela vous permettra également d'utiliser des analyseurs personnalisés que vous avez écrits et qui devraient fonctionner pour toujours, par exemple:

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

Voici mon code complet avec des descriptions de méthode.

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;
    }
}
9
répondu Jamie Bell 2014-03-29 01:06:04

Pour ne faire correspondre que des entiers de base-dix positifs, qui ne contiennent que des chiffres ASCII, utilisez:

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

Une approche performante évitant try-catch et manipulant les nombres négatifs et la notation scientifique.

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
répondu lars 2015-04-08 14:42:16

Voici ma classe pour vérifier si une chaîne est numérique. Il corrige également les chaînes numériques:

Caractéristiques:

  1. Supprime les zéros inutiles ["12.0000000" -> "12"]
  2. Supprime les zéros inutiles ["12.0580000" -> "12.058"]
  3. supprime les caractères non numériques ["12. 00sdfsdf00" -> "12"]
  4. gère les valeurs de chaîne négatives ["-12,020000" -> "-12.02"]
  5. Supprime plusieurs points ["-12.0.20.000" -> "-12.02"]
  6. Pas de bibliothèques supplémentaires, juste standard Java

Voilà...

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
répondu Meatball 2015-04-28 06:15:54

Les Exceptions sont coûteuses, mais dans ce cas, L'expression rationnelle prend beaucoup plus de temps. Le code ci-dessous montre un test simple de deux fonctions-Une utilisant des exceptions et une utilisant regex. Sur ma machine, la version RegEx est 10 fois plus lente que l'exception.

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
répondu ChrisCantrell 2015-06-18 13:52:33

L'Expression Rationnelle Correspondant

Voici un autre exemple mis à jour" CraigTP " regex correspondant à plus de validations.

public static boolean isNumeric(String str)
{
    return str.matches("^(?:(?:\\-{1})?\\d+(?:\\.{1}\\d+)?)$");
}
  1. Seulement un signe négatif - autorisé et doit être au début.
  2. après signe négatif, il doit y avoir un chiffre.
  3. un seul signe décimal . autorisé.
  4. après le signe décimal, il doit y avoir un chiffre.

Test Regex

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
4
répondu Madan Sapkota 2015-06-15 06:10:35

/ / Veuillez vérifier ci-dessous le code

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
répondu Tejas Parmar 2016-09-16 12:57:17

C'est pourquoi j'aime L'approche Try* dans. NET. en plus de la méthode D'analyse traditionnelle qui est comme celle de Java, vous avez également une méthode TryParse. Je ne suis pas bon dans la syntaxe Java (out paramètres?), veuillez donc traiter ce qui suit comme une sorte de pseudo-code. Il devrait rendre le concept clair cependant.

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

Utilisation:

int num;
if (parseInteger("23", out num)) {
    // Do something with num.
}
3
répondu OregonGhost 2014-11-06 12:22:17
// 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
répondu Elye M. 2015-04-06 01:32:17

Ceci est un exemple simple pour cette vérification:

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
répondu ARIJIT 2015-04-06 01:35:04

Analyser (c'est à dire avec Integer#parseInt ) et tout simplement attraper l'exception. =)

Pour clarifier: la fonction parseInt vérifie si elle peut analyser le nombre dans tous les cas (évidemment) et si vous voulez l'analyser de toute façon, vous n'allez pas prendre de performance en faisant réellement l'analyse.

Si vous ne voulez pas l'analyser (ou l'analyser très, très rarement), vous voudrez peut-être le faire différemment bien sûr.

2
répondu gha.st 2015-04-06 01:15:37

Vous pouvez utiliser java.util.Objet Scanner.

public static boolean isNumeric(String inputData) {
      Scanner sc = new Scanner(inputData);
      return sc.hasNextInt();
    }
2
répondu Yu Wai Hlaing 2015-08-19 07:52:20

Voici deux méthodes qui pourraient travailler. (Sans utiliser D'Exceptions). Remarque: Java est une valeur pass-by-value par défaut et la valeur D'une chaîne est l'adresse des données d'objet de la chaîne. Alors, quand vous faites

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

Vous avez modifié la valeur d'entrée pour ne pas avoir d'espaces. Vous pouvez supprimer cette ligne si vous voulez.

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

Voici une autre méthode au cas où vous souhaitez autoriser les flotteurs Cette méthode permet prétendument aux nombres dans le formulaire de passer 1,123,123,123,123,123.123 je viens de faire , et je pensez qu'il a besoin de tests supplémentaires pour s'assurer qu'il fonctionne.

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
répondu XForCE07 2013-04-20 11:15:26

J'ai modifié la solution de CraigTP pour accepter la notation scientifique et les points et les virgules comme séparateurs décimaux

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

Exemple

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
1
répondu AndyTheEntity 2013-12-05 14:40:17

Vous pouvez utiliser NumberUtils.isCreatable() de Apache Commons Lang.

Depuis NumberUtils.isNumber sera obsolète dans 4.0, utilisez donc NumberUtils.isCreatable () à la place.

1
répondu Cenxui 2016-11-13 13:40:22

C'est le moyen le plus rapide que je connaisse de vérifier si String est Number ou non:

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
répondu user3870075 2017-04-09 12:10:37

La vérification Parallèle pour très longues chaînes de caractères à l'aide de IntStream

Dans Java 8, les tests suivants si tous les caractères du string donné sont compris entre ' 0 ' et '9'. Rappelez-vous que la chaîne vide est acceptée:

string.chars().unordered().parallel().allMatch( i -> '0' <= i && '9' >= i )
1
répondu Bernhard Bodenstorfer 2018-05-25 07:22:28

Si vous utilisez la méthode suivante pour vérifier:

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

Alors ce qui s'est passé avec l'entrée de très longue chaîne, comme j'appelle cette méthode:

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

Le résultat est "vrai", c'est aussi un nombre trop grand! La même chose se produira si vous utilisez regex pour vérifier! Donc, je préfère utiliser la méthode "parsing" pour vérifier, comme ceci:

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

Et le résultat est ce à quoi je m'attendais!

1
répondu Tạ Anh Tú 2018-09-18 07:37:36

Je pense que la seule façon de dire de manière fiable si une chaîne est un nombre, est de l'analyser. Donc, je voudrais juste de l'analyser, et si c'est un nombre, vous obtenez le nombre dans un int pour libre!

0
répondu jqno 2009-07-09 09:54:05