Comment vérifier si une Chaîne est numérique en Java
Comment voulez-vous vérifier si une Chaîne est un nombre avant de l'analyser?
- Toutes les solutions proposées avec les expressions régulières ne fonctionnera pas pour les nombres hexadécimaux.
- et en passant null chaîne correspond à(...) va jeter NullPointer exception.
- Voir Max Malysh de réponse concise Java 8 solution sans les bibliothèques de tiers.
- null chaînes semblent être normalement traitées dans la version la plus récente (y compris la version 6 de Java.x et 7.x)
- Toutes les solutions proposées pour l'utilisation
Integer.parseInt()
échoue à analyser les numéros de téléphone mobile avecNumberFormatException
. - Toutes les chaînes sont des nombres dans une base donnée.
Vous devez vous connecter pour publier un commentaire.
Avec Apache Commons Lang 3.5 et ci-dessus:
NumberUtils.isCreatable
ouStringUtils.isNumeric
.Avec Apache Commons Lang 3.4 et ci-dessous:
NumberUtils.isNumber
ouStringUtils.isNumeric
.Vous pouvez également utiliser
StringUtils.isNumericSpace
qui renvoietrue
pour les cordes à vide, et ignore les espaces internes de la chaîne. Une autre façon est d'utiliser desStringUtils.isParsable
qui, fondamentalement, vérifie le nombre est analysée en fonction de Java. (Liés javadocs contiennent des exemples détaillés pour chaque méthode.)StringUtils.isNumeric()
ne serait probablement pas approprié ici, car il vérifie uniquement si la chaîne est une séquence de chiffres. Ce serait bien pour la plupart des services de renseignements, mais pas pour les nombres avec décimales, séparateurs de groupes, etc.StringUtils
ne prend pas en charge les principaux signes, mais vous devriez vérifierNumberUtils.isCreatable
, il prend en charge les négatifs correctement.Cela se fait généralement avec une simple fonction définie par l'utilisateur (c'est à dire Rouler "isNumeric" de la fonction).
Quelque chose comme:
Toutefois, si vous êtes à l'appel de cette fonction beaucoup, et vous vous attendez à de nombreux contrôles à l'échec en raison de ne pas être un numéro, puis les performances de ce mécanisme ne sera pas grande, puisque vous êtes s'appuyer sur l'exception levée pour chaque échec, ce qui est relativement coûteuse opération.
Une approche alternative peut être d'utiliser une expression régulière pour vérifier la validité d'un numéro:
Être prudent avec les RegEx mécanisme, bien que, comme il va échouer si vous utilisez la non-chiffres arabes (c'est à dire de chiffres autres qu'0 à 9). C'est parce que le "\d" une partie de la RegEx ne match [0-9] et efficace n'est pas à l'échelle internationale numériquement au courant. (Merci à OregonGhost pour le signaler!)
Ou même une autre alternative est d'utiliser Java intégré dans java.texte.NumberFormat objet pour voir si, après l'analyse de la chaîne de l'analyseur est la position à la fin de la chaîne. Si elle l'est, nous pouvons présumer que l'ensemble de la chaîne numérique:
.
dans votre expression régulière correspond à tout caractère, et pas seulement le caractère séparateur décimal.(\\+|-)?\\d+(\\.\\d+)?
comme"+1.20"
est une valeur numérique valide.return str.matches("\\d") && str.matches("^[+-]?\\d*\\.?\\d*([eE]\\d)?\\d*$");
.006
et0.
- ceux-ci sont valables aussi.,
?Integer.parseInt()
deux fois sur la même entrée. La bonne solution est d'appeler une fois, en cas de besoin, et de les attraper et de les traiter avec leNumberFormatException
telle qu'elle se pose.si vous êtes sur android, alors vous devriez utiliser:
la documentation peut être trouvée ici
keep it simple. surtout que tout le monde peut "re-programme" (la même chose).
.
,-
Comme @CraigTP l'avait mentionné dans son excellente réponse, j'ai également avoir des problèmes de performances sur l'utilisation d'Exceptions pour vérifier si la chaîne est numérique ou pas. Donc je me retrouve fractionnement de la chaîne et de l'utilisation
java.lang.Character.isDigit()
.Selon la Javadoc,
Character.isDigit(char)
correctement reconnaît non latine chiffres. En terme de Performance, je pense qu'un simple N nombre de comparaisons où N est le nombre de caractères dans la chaîne seraient plus efficaces de calcul que de faire une regex de correspondance.Mise à JOUR: Comme indiqué par Jean-François Corbett dans le commentaire, le code ci-dessus serait seulement de valider les entiers positifs, qui couvre la majorité de mon cas d'utilisation. Ci-dessous la mise à jour du code qui valide correctement les nombres décimaux selon les paramètres régionaux par défaut utilisée dans votre système, avec l'hypothèse que le séparateur décimal ne se produisent une fois dans la chaîne.
if
à quelque chose comme:boolean isMinus = str.charAt(0) == localeMinusSign; if ((isMinus && str.length() < 2) || ((!isMinus) && !Character.isDigit(str.charAt(0)))) { return false; }
toCharArray()
va créer une copie du tableau dans la Chaîne de l'objet, car les Chaînes sont immuables. Probablement plus rapide d'utiliser lecharAt(int index)
méthode sur l'objet de type String directement.StringIndexOutOfBoundsException
lorsqu'il est passé d'une chaîne de longueur 0. Peut être fixé avecif(str.length() == 0) return false;
Java 8 les expressions lambda.
Google Goyave bibliothèque fournit une bonne méthode d'assistance pour ce faire:
Ints.tryParse
. Vous l'utilisez comme uneInteger.parseInt
mais il renvoienull
plutôt que de lever une Exception si la chaîne de ne pas analyser à un entier valide. Notez qu'il retourne Entier, et non pas de type int, donc vous devez le convertir/autobox de retour à l'int.Exemple:
Cependant, la version actuelle -- Goyave r11 -- elle est encore marquée @Bêta.
Je n'ai pas comparé ça. En regardant le code source il y a une surcharge de 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 de gestion des exceptions la surcharge sous les couvertures dans leur mise en œuvre.Ne pas utiliser les Exceptions pour valider vos valeurs.
Utilisation Util libs comme apache NumberUtils:
Modifier:
Veuillez noter que, si votre chaîne de caractères commence par un 0, NumberUtils interprétera votre valeur hexadécimale.
Number.isNumber()
.Number.isNumber()
est présent depuis la première version de la réponse, datée Sep 24 '12 à 17:01.Pourquoi tout le monde en poussant d'exception/regex solutions?
Même si je peux comprendre la plupart des gens sont beaux, avec l'aide de try/catch, si vous voulez le faire souvent... il peut être extrêmement pénible.
Ce que j'ai fait ici est de prendre la regex, le parseNumber() les méthodes, et la matrice de méthode de recherche afin de voir laquelle est la plus efficace. Cette fois, j'ai seulement regardé des nombres entiers.
Les résultats de la vitesse que j'ai sont:
Avertissement: je ne dis pas que ces méthodes sont 100% optimisé, ils sont juste là pour la démonstration de 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 ont même un chèque?
En bref, c'est extrêmement douloureux si vous exécutez dans les numéros non valides fréquemment avec le try/catch, qui fait sens. Une règle importante, j'ai toujours suivre est ne JAMAIS utiliser try/catch pour le flux de programme. Ceci est un exemple de pourquoi.
Fait intéressant, le plus simple si char <0 || >9 est extrêmement simple à écrire, facile à retenir (et doit travailler dans plusieurs langues) et gagne presque tous les scénarios de test.
Le seul inconvénient est que je devine Entier.parseInt() peut-poignée non ASCII des chiffres, alors que le tableau de méthode de recherche ne fonctionne pas.
Pour ceux qui se demandent pourquoi j'ai dit que c'est facile de se rappeler le tableau de caractères, si vous le savez il n'y a pas de signes négatifs, vous pouvez facilement obtenir loin avec quelque chose de résumés comme ceci:
Enfin comme note finale, j'étais curieux de connaître l'affectation de l'opérateur dans l'acceptation exemple avec tous les votes jusqu'. L'ajout de la cession de l'
n'est pas seulement inutile, puisque vous n'avez même pas utiliser la valeur, mais il gaspille du temps de traitement et l'augmentation de l'exécution de quelques nanosecondes (qui a conduit à une 100-200 ms augmentation dans les tests). Je ne vois pas pourquoi quelqu'un voudrait le faire car c'est réellement un travail supplémentaire pour réduire les performances.
Vous pensez que ce serait optimisé à... mais je devrais peut-être vérifier le pseudo-code et voir ce que le compilateur est en train de faire. Cela n'explique pas pourquoi il a toujours montré comme plus long pour moi mais si de toute façon il est optimisé pour sortir... donc je me demande ce qu'il se passe. Comme une note: En plus long, je veux dire l'exécution de l'essai pour 10000000 itérations, et l'exécution de ce programme plusieurs fois (10x+) toujours montré pour être plus lent.
EDIT: mise à Jour d'un test de Caractère.appel isdigit()
CraigTP de l'expression régulière (voir ci-dessus) produit des faux positifs. E. g. "23y4" sera compté comme un nombre, parce que '.' correspond à tout caractère qui n'est pas le point décimal.
Aussi il rejeter un nombre précédé d'un '+'
Une alternative qui permet d'éviter ces deux problèmes mineurs est
true
pour un seul plus"+"
ou moins"-"
, etfalse
pour"0."
"0."
est valable pourDouble.parseDouble()
et est valable littérale selon la JLS (§3.10.2)!"21a12".matches("-?\\d+(.\\d+)?")
retourne vrai!!!matches("-?\\d+([.]\\d+)?")
[+-]?(\\d\\.)?\\d+
devrait mieux fonctionnerVous pouvez utiliser
NumberFormat#parse
:value
.On peut essayer de les remplacer tous les nombres de la chaîne ("") c'est à dire vide de l'espace, et si après que la longueur de la chaîne est à zéro, alors on peut dire que la chaîne ne contient que des chiffres. [Si vous avez trouvé cette réponse utile alors s'il vous plaît ne considérez jusqu'à droit de vote de celle-ci]
Exemple:
""
est un nombre, mais"3.14"
et"-1"
ne le sont pas?Si vous utiliser java pour développer des applications Android, vous pouvez à l'aide de TextUtils.isDigitsOnly fonction.
C'était ma réponse à ce problème.
Un fourre-tout confort 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 unClass
ou unobject
. Cela vous permet également d'utiliser des analyseurs vous avez écrit et doivent travailler pour toujours le scénario, par exemple:Voici mon code avec la méthode des descriptions.
Pour correspondre seul point positif de base dix entiers, qui ne contient que des caractères ASCII, utilisez:
Un performant approche en évitant try-catch et à la manipulation des nombres négatifs et de la notation scientifique.
Voici ma classe pour vérifier si une chaîne de caractères numériques. Il fixe également des chaînes numériques:
Caractéristiques:
Ici vous allez...
Voici un autre exemple de mise à niveau "CraigTP" regex correspondance avec plus de validations.
Exceptions sont chers, mais dans ce cas, la RegEx prend beaucoup plus de temps. Le code ci-dessous montre un simple test de deux fonctions, l'une à l'aide d'exceptions et une à l'aide de regex. Sur ma machine la RegEx version est 10 fois plus lent que l'exception.
//s'il vous plaît vérifier ci-dessous le code
Présente un exemple simple de cette vérification:
Vous pouvez utiliser le java.util.Scanner objet.
J'ai modifié CraigTP solution à accepter la notation scientifique et à la fois le point et la virgule comme séparateur décimal ainsi
exemple
C'est pourquoi j'aime l'Essayer* approche .NET. En plus de la traditionnelle méthode d'analyse qui est comme le code Java, vous avez également une méthode TryParse. Je ne suis pas bon dans la syntaxe Java (paramètres de sortie?), donc, veuillez considérer ce qui suit comme une sorte de pseudo-code. Il devrait rendre le concept plus clair.
Utilisation:
L'analyser (c'est à dire avec
Integer#parseInt
) et il suffit d'intercepter l'exception. =)Pour clarifier: Le parseInt fonction vérifie si il peut analyser le nombre dans tous les cas (évidemment) et si vous voulez analyser, de toute façon, vous n'allez pas prendre toutes les performances en faisant l'analyse.
Si vous ne voulez pas de l'analyser (ou à analyser de très très rarement) que vous pourriez souhaiter faire les choses différemment, bien sûr.
Vous pouvez utiliser NumberUtils.isCreatable() à partir de Apache Commons Lang.
Depuis NumberUtils.isNumber sera obsolète dans la version 4.0, afin de l'utiliser NumberUtils.isCreatable() à la place.
Java 8 des Flux, de la lambda expression, interface fonctionnelle
Tous les cas traités (chaîne null, chaîne vide etc)
J'ai illustré certaines conditions à vérifier les chiffres et de décimales sans l'aide d'une API,
Vérifier la Correction de Longueur 1 chiffres
Vérifier la Correction de Longueur (numéro d'Assumer la longueur est de 6)
Case à Longueur Variable nombre entre (à Supposer de 4 à 6 longueur)
Case à Longueur Variable nombre décimal entre (à Supposer de 4 à 7 longueur)
Espère que ça aidera manyone.
À partir d'autres réponses, j'ai écrit mon propre et il n'utilise pas de modèles ou de l'analyse, à l'exception de la vérification.
Il vérifie pour un maximum de un signe et des chèques pour une durée maximale d'un point décimal.
Voici quelques exemples et leurs résultats:
"1", "-1", "-1.5" et "-1.556" return true
"1..5", "1A.5", "1.5 D", "-" et "--1" return false
Remarque: Si nécessaire, vous pouvez modifier ce à accepter un paramètre local et le passer dans la DecimalFormatSymbols.getInstance() appelle à l'utilisation d'une Locale au lieu de l'actuel.
Voici deux méthodes qui pourraient travailler. (Sans l'aide d'Exceptions).
Remarque : Java est un passe-par-valeur par défaut et d'une Chaîne de valeur est l'adresse de la Chaîne de l'objet de données.
Donc , quand vous faites
Vous avez modifié la valeur d'entrée n'ont pas d'espaces.
Vous pouvez supprimer cette ligne si vous le souhaitez.
Voici une autre méthode dans le cas où vous souhaitez autoriser les flotteurs
Cette méthode prétendument permet aux nombres sous forme de pass
1,123,123,123,123,123.123
je viens de faire , et je pense qu'il a besoin de plus de tests pour s'assurer qu'il fonctionne.
Vous pouvez utiliser
BigDecimal
si la chaîne peut contenir des décimales:C'est le plus rapide que je connaisse pour vérifier si la Chaîne est le Nombre ou pas:
Vérification parallèle pour très long des chaînes à l'aide de IntStream
Dans Java 8, les tests suivants si tous les caractères de la donnée
string
sont à l'intérieur de '0' à '9'. L'esprit que la chaîne vide est acceptée:Les gars si vous utilisez la méthode suivante pour vérifier:
Puis ce qui s'est vraiment passé avec l'entrée de Chaîne très longue, comme je l'ai appeler cette méthode:
Le résultat est "vrai", il est aussi un trop grand nombre de taille!
La même chose se produira si vous en utilisant les regex pour vérifier!
Donc, je préfère utiliser le "parsing" méthode pour vérifier, comme ceci:
Et le résultat est ce que j'attendais!
7645
est un nombre et92847294729492875982452012471041141990140811894142729051
est aussi un nombre. La première peut être représenté comme uneInteger
et la seconde peut être représenté comme unBigDecimal
. Et même si ils ne pouvaient pas être représenté comme un objet en Java, ils sont encore en nombre, qui est ce que la question demande.NumberFormatException
Je pense que le seul moyen fiable de savoir si une chaîne est un nombre, est à analyser. Donc, je voudrais juste de l'analyser, et si c'est un nombre, vous obtenez le nombre dans un int pour gratuit!
Si vous voulez faire la vérification à l'aide d'une regex vous devez créer un Modèle statique de l'objet, de sorte que la regex n'a besoin d'être compilé une fois. La compilation de la regex faut autant de temps que l'exécution du match en prenant cette précaution, vous réduisez le temps d'exécution de la méthode dans la moitié.
Je suis en supposant un nombre est une chaîne de caractères avec rien, mais les chiffres décimaux, y a + ou le signe - au début et à la plupart un point décimal (pas à la fin) et pas d'autres caractères (y compris les virgules, les espaces, les chiffres dans d'autres systèmes de comptage, des chiffres Romains, des hiéroglyphes).
Cette solution est succincte et assez vite, mais vous permet de vous raser quelques millisecondes par million d'invocations en faisant comme ceci
Essayez ceci: