Quel est le moyen le plus propre et le plus efficace de valider des nombres décimaux en JavaScript?
Points bonus pour:
- Clarté. La solution doit être propre et simple.
- Multiplateforme.
Cas de test:
01. IsNumeric('-1') => true
02. IsNumeric('-1.5') => true
03. IsNumeric('0') => true
04. IsNumeric('0.42') => true
05. IsNumeric('.42') => true
06. IsNumeric('99,999') => false
07. IsNumeric('0x89f') => false
08. IsNumeric('#abcdef') => false
09. IsNumeric('1.2.3') => false
10. IsNumeric('') => false
11. IsNumeric('blah') => false
javascript
validation
numbers
Michael Haren
la source
la source
jQuery.isNumeric
fonction utilitaire: api.jquery.com/jQuery.isNumericjQuery.isNumeric
échouera au septième cas de test de l'OP (IsNumeric('0x89f') => *false*
). Je ne sais pas si je suis d'accord avec ce cas de test, cependant.Réponses:
@ La réponse de Joel est assez proche, mais elle échouera dans les cas suivants:
Il y a quelque temps, j'ai dû implémenter une
IsNumeric
fonction, pour savoir si une variable contenait une valeur numérique, quel que soit son type , elle pouvait être uneString
contenant une valeur numérique (je devais considérer aussi la notation exponentielle, etc.), unNumber
objet, pratiquement tout pouvait être transmis à cette fonction, je ne pouvais pas faire d'hypothèses de type, en prenant soin de la contrainte de type (par exemple,+true == 1;
maistrue
ne devrait pas être considéré comme"numeric"
).Je pense qu'il vaut la peine de partager cet ensemble de tests unitaires +30 effectués sur de nombreuses implémentations de fonctions, et de partager celui qui réussit tous mes tests:
PS isNaN & isFinite ont un comportement déroutant en raison de la conversion forcée en nombre. Dans ES6, Number.isNaN & Number.isFinite résoudrait ces problèmes. Gardez cela à l'esprit lorsque vous les utilisez.
Mise à jour : voici comment jQuery le fait maintenant (2.2-stable) :
Mise à jour : Angular 4.3 :
la source
2e308 > Number.MAX_VALUE
depuis2e308 == Infinity
. Si vous voulez une fonction qui renvoietrue
également des valeurs d'infini positives et négatives, vérifiez la fonction n ° 2 dans la suite de tests . À votre santé.Arrrgh! N'écoutez pas les réponses d'expression régulière. RegEx est exagéré pour cela, et je ne parle pas seulement de performances. Il est si facile de faire des erreurs subtiles, impossibles à repérer avec votre expression régulière.
Si vous ne pouvez pas l'utiliser
isNaN()
, cela devrait fonctionner beaucoup mieux:Voici comment ça fonctionne:
L'
(input - 0)
expression force JavaScript à effectuer une coercition de type sur votre valeur d'entrée; il doit d'abord être interprété comme un nombre pour l'opération de soustraction. Si cette conversion en un nombre échoue, l'expression se traduira parNaN
. Ce résultat numérique est ensuite comparé à la valeur d'origine que vous avez transmise. Comme le côté gauche est désormais numérique, le type coercition est à nouveau utilisé. Maintenant que l'entrée des deux côtés a été contrainte au même type à partir de la même valeur d'origine, vous penseriez qu'ils devraient toujours être les mêmes (toujours vrai). Cependant, il existe une règle spéciale qui ditNaN
n'est jamais égal àNaN
, et donc une valeur qui ne peut pas être convertie en nombre (et seules les valeurs qui ne peuvent pas être converties en nombres) se traduira par false.Le contrôle de la longueur concerne un cas particulier impliquant des chaînes vides. Notez également qu'il tombe sur votre test 0x89f, mais c'est parce que dans de nombreux environnements, c'est une bonne façon de définir un nombre littéral. Si vous souhaitez intercepter ce scénario spécifique, vous pouvez ajouter une vérification supplémentaire. Encore mieux, si c'est votre raison de ne pas l'utiliser,
isNaN()
enveloppez simplement votre propre fonctionisNaN()
qui peut également faire la vérification supplémentaire.En résumé, si vous voulez savoir si une valeur peut être convertie en nombre, essayez en fait de la convertir en nombre.
Je suis retourné et j'ai fait des recherches pour savoir pourquoi une chaîne d'espaces blancs n'avait pas la sortie attendue, et je pense que je l'obtiens maintenant: une chaîne vide est contrainte à
0
plutôt queNaN
. Il suffit de couper la chaîne avant la vérification de la longueur pour gérer ce cas.Exécuter les tests unitaires contre le nouveau code et il échoue uniquement sur les littéraux infini et booléen, et le seul moment qui devrait être un problème est si vous générez du code (vraiment, qui taperait un littéral et vérifierait s'il est numérique? Vous devez savoir ), et ce serait un code étrange à générer.
Mais, encore une fois, la seule raison de l'utiliser est si, pour une raison quelconque, vous devez éviter isNaN ().
la source
IsNumeric(' ')
,IsNumeric('\n\t')
etc. tous les retourstrue
Number
littérale deIsNumeric(5) == false;
l'ensemble des tests unitaires que j'ai publiés, cette fonction est le numéro16
de la suite de tests. stackoverflow.com/questions/18082/…Cette façon semble bien fonctionner:
En une seule ligne:
Et pour le tester:
J'ai emprunté cette expression régulière à http://www.codetoad.com/javascript/isnumeric.asp . Explication:
la source
Yahoo! L'interface utilisateur utilise ceci:
la source
new Number(1)
.Cela fonctionne également pour les numéros de type 0x23.
la source
IsNumeric('')
,IsNumeric(' ')
,IsNumeric(true)
,IsNumeric(false)
,IsNumeric(null)
Retour autrue
lieu defalse
.La réponse acceptée a échoué à votre test n ° 7 et je suppose que c'est parce que vous avez changé d'avis. C'est donc une réponse à la réponse acceptée, avec laquelle j'ai eu des problèmes.
Au cours de certains projets, j'ai dû valider certaines données et être aussi certain que possible qu'il s'agit d'une valeur numérique javascript qui peut être utilisée dans des opérations mathématiques.
jQuery et certaines autres bibliothèques javascript incluent déjà une telle fonction, généralement appelée
isNumeric
. Il existe également un article sur stackoverflow qui a été largement accepté comme réponse, la même routine générale que les bibliothèques susmentionnées utilisent.Tout d'abord, le code ci-dessus retournerait vrai si l'argument était un tableau de longueur 1 et que cet élément unique était d'un type considéré comme numérique par la logique ci-dessus. À mon avis, si c'est un tableau, ce n'est pas numérique.
Pour atténuer ce problème, j'ai ajouté une vérification pour actualiser les tableaux de la logique
Bien sûr, vous pouvez également utiliser
Array.isArray
, jquery$.isArray
ou prototypeObject.isArray
au lieu deObject.prototype.toString.call(n) !== '[object Array]'
Mon deuxième problème était que les chaînes littérales entières hexadécimales négatives ("-0xA" -> -10) n'étaient pas comptées comme numériques. Cependant, les chaînes littérales entières hexadécimales positives ("0xA" -> 10) ont été traitées comme des valeurs numériques. J'avais besoin des deux pour être numérique valide.
J'ai ensuite modifié la logique pour en tenir compte.
Si vous êtes inquiet à propos de la création de l'expression régulière à chaque appel de la fonction, vous pouvez la réécrire dans une fermeture, quelque chose comme ceci
J'ai ensuite pris des cas de test CMS +30 et cloné les tests sur jsfiddle ajouté mes cas de test supplémentaires et ma solution décrite ci-dessus.
Cela ne remplacera peut-être pas la réponse largement acceptée / utilisée, mais si c'est plus ce à quoi vous vous attendez en tant que résultats de votre fonction isNumeric, nous espérons que cela vous sera utile.
EDIT: Comme l'a souligné Bergi , il existe d'autres objets possibles qui pourraient être considérés comme numériques et il serait préférable de mettre sur liste blanche que sur liste noire. Dans cet esprit, j'ajouterais aux critères.
Je souhaite que ma fonction isNumeric prenne en compte uniquement les nombres ou les chaînes
Dans cette optique, il serait préférable d'utiliser
Testez les solutions
la source
IsNumeric('99,999') => false
Ouais, le intégré
isNaN(object)
sera beaucoup plus rapide que toute analyse syntaxique de regex, car il est intégré et compilé, au lieu d'être interprété à la volée.Bien que les résultats soient quelque peu différents de ce que vous recherchez ( essayez-le ):
la source
Utilisez la fonction
isNaN
. Je crois que si vous testez,!isNaN(yourstringhere)
cela fonctionne bien pour l'une de ces situations.la source
Depuis jQuery 1.7, vous pouvez utiliser
jQuery.isNumeric()
:Notez simplement que contrairement à ce que vous avez dit,
0x89f
est un nombre valide (hexa)la source
Cela peut être fait sans RegExp comme
la source
Je me rends compte que la question d'origine ne mentionnait pas jQuery, mais si vous utilisez jQuery, vous pouvez faire:
Facile.
https://api.jquery.com/jQuery.isNumeric/ (à partir de jQuery 1.7)
la source
n'a pas fonctionné pour moi. Quand j'ai mis une alerte et testé,
input.length
c'étaitundefined
. Je pense qu'il n'y a aucune propriété pour vérifier la longueur entière. Donc ce que j'ai faitCela a bien fonctionné.
la source
Si je ne me trompe pas, cela devrait correspondre à toute valeur de numéro JavaScript valide, à l'exclusion des constantes (
Infinity
,NaN
) et des opérateurs de signe+
/-
(car ils ne font pas réellement partie du nombre en ce qui me concerne, ce sont des opérateurs distincts):J'en avais besoin pour un tokenizer, où l'envoi du numéro à JavaScript pour évaluation n'était pas une option ... Ce n'est certainement pas l'expression régulière la plus courte possible, mais je pense qu'il capture toutes les subtilités les plus fines de la syntaxe numérique de JavaScript.
Les nombres valides comprennent:
Des nombres invalides seraient
la source
Le seul problème que j'ai eu avec la réponse de @ CMS est l'exclusion de
NaN
et Infinity, qui sont des numéros utiles dans de nombreuses situations. Une façon de vérifierNaN
l » est de vérifier les valeurs numériques qui ne sont pas eux - mêmes égaux,NaN != NaN
! Il y a donc vraiment 3 tests que vous aimeriez traiter ...My isComparableNumber est assez proche d'une autre réponse élégante , mais gère les représentations hexadécimales et autres chaînes de nombres.
la source
Pour moi, c'est la meilleure façon:
la source
Je voudrais ajouter ce qui suit:
Les nombres hexadécimaux positifs commencent par
0x
et les nombres hexadécimaux négatifs commencent par-0x
. Les nombres d'octets positifs commencent par0
et les nombres d'octets négatifs commencent par-0
. Celui-ci prend en compte la plupart de ce qui a déjà été mentionné, mais comprend les nombres hexadécimaux et octaux, scientifique négatif, Infinity et a supprimé scientifique décimal (4e3.2
n'est pas valide).la source
Je pense que la fonction parseFloat peut faire tout le travail ici. La fonction ci-dessous passe tous les tests de cette page, notamment
isNumeric(Infinity) == true
:la source
IsNumeric([3]) == true;
IsNumeric([]) == false;
IsNumeric([3, 4]) == false;
mais j'imagine que c'est une question de goût!Quelques tests à ajouter:
Je suis venu avec ceci:
La solution couvre:
la source
Une valeur entière peut être vérifiée par:
De cette façon, c'est plus facile et plus rapide! Tous les tests sont vérifiés!
la source
Voici une version légèrement améliorée (probablement le moyen le plus rapide) que j'utilise à la place de la variante exacte de jQuery, je ne sais vraiment pas pourquoi ils n'utilisent pas celui-ci:
L'inconvénient de la version de jQuery est que si vous passez une chaîne avec des chiffres de début et des lettres de fin comme
"123abc"
leparseFloat | parseInt
va extraire la fraction numérique et retourner 123, MAIS, le deuxième gardeisFinite
échouera quand même. Avec l'+
opérateur unaire , il mourra sur le tout premier garde puisque + lance NaN pour de tels hybrides :) Un peu de performance pourtant je pense un solide gain sémantique.la source
Ma solution,
Cela semble fonctionner dans toutes les situations, mais je peux me tromper.
la source
?
pour{0,1}
et\d
pour[0-9]
. De plus+
, puis en l'enveloppant(?:){0,1}
, vous pouvez aussi utiliser*
et oublier les groupes (non) capturés.J'utilise une solution plus simple:
la source
Cela devrait fonctionner. Certaines des fonctions fournies ici sont défectueuses et devraient également être plus rapides que toute autre fonction ici.
Expliqué:
Créez une copie de lui-même, puis convertissez le nombre en flottant, puis comparez-le avec le nombre d'origine, s'il s'agit toujours d'un nombre (entier ou flottant), et correspond au nombre d'origine, c'est-à-dire qu'il s'agit bien d'un nombre.
Il fonctionne avec des chaînes numériques ainsi que des nombres simples. Ne fonctionne pas avec des nombres hexadécimaux.
Attention: utilisez à vos risques et périls, aucune garantie.
la source
Aucune des réponses ne renvoie
false
pour les chaînes vides, un correctif pour cela ...la source
Pour vérifier si une variable contient un nombre valide et pas seulement une chaîne qui ressemble à un nombre,
Number.isFinite(value)
peut être utilisée.Cela fait partie du langage depuis ES2015
Exemples:
la source
Number.isFinite('0') -> false
Si n est numérique
Number(n)
, la valeur numérique sera retournée et latoString()
transformera en chaîne. Mais si n n'est pas numérique,Number(n)
il reviendraNaN
donc il ne correspondra pas à l'originaln
la source
Je me rends compte que cela a été répondu plusieurs fois, mais ce qui suit est un candidat décent qui peut être utile dans certains scénarios.
il convient de noter qu'il suppose que «.42» n'est pas un nombre, et «4.» n'est PAS un nombre, il faut donc en tenir compte.
Le
isDecimal
réussit le test suivant:L'idée ici est que chaque nombre ou entier a une représentation de chaîne "canonique", et chaque représentation non canonique doit être rejetée. Donc, nous convertissons en nombre et en arrière, et voyons si le résultat est la chaîne d'origine.
L'utilité de ces fonctions dépend du cas d'utilisation. Une caractéristique est que les chaînes distinctes représentent des nombres distincts (si les deux réussissent le
isNumber()
test).Cela est pertinent, par exemple pour les nombres comme noms de propriété d'objet.
la source
Fonctions de validation de la bibliothèque knockoutJs Inbuild
En l'étendant, le champ est validé
1) numéro
self.number = ko.observable(numberValue)
.extend ({nombre: vrai}) ;Cas de test
2) chiffre
self.number = ko.observable(numberValue)
.extend ({chiffre: vrai}) ;Cas de test
3) min et max
self.number = ko.observable(numberValue)
.extend ({min: 5}). extend ({max: 10}) ;Ce champ accepte uniquement les valeurs comprises entre 5 et 10
Cas de test
la source
Si vous devez valider un ensemble spécial de décimales, vous pouvez utiliser ce simple javascript:
http://codesheet.org/codesheet/x1kI7hAD
Le Javascript:
la source
isNumeric=(el)=>{return Boolean(parseFloat(el)) && isFinite(el)}
Rien de bien différent mais on peut utiliser le constructeur booléen
la source