Valider les nombres décimaux dans JavaScript-IsNumeric()

Quel est le moyen le plus propre et le plus efficace de valider les nombres décimaux en JavaScript?

points Bonus pour:

  1. clarté. La Solution doit être propre et simple.
  2. cross-platform.

cas D'essai:

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
2179
demandé sur Michael Haren 2008-08-20 18:21:13

30 réponses

la réponse de @Joel est assez proche, mais elle échouera dans les cas suivants:

// Whitespace strings:
IsNumeric(' ')    == true;
IsNumeric('\t\t') == true;
IsNumeric('\n\r') == true;

// Number literals:
IsNumeric(-1)  == false;
IsNumeric(0)   == false;
IsNumeric(1.1) == false;
IsNumeric(8e5) == false;

il y a quelque temps, j'ai dû implémenter une fonction IsNumeric , pour savoir si une variable contenait une valeur numérique, quel que soit son type , il pourrait s'agir d'une String contenant une valeur numérique (j'ai dû aussi prendre en compte la notation exponentielle, etc.), un objet Number , presque tout peut être passé à cette fonction, Je ne pouvais pas faire toutes les hypothèses de type, en prenant soin de type coercition (par ex. +true == 1; mais true ne doit pas être considéré comme "numeric" ).

je pense qu'il vaut la peine de partager cet ensemble de +30 tests unitaires fait à de nombreuses implémentations de fonction, et aussi partager celui qui passe tous mes tests:

function isNumeric(n) {
    return !isNaN(parseFloat(n)) && isFinite(n);
}

P. S. isNaN & isFinite ont un comportement confus dû à la conversion forcée en nombre. En ES6, le numéro .isNaN & Number.isFinite réglerait ces problèmes. Gardez cela à l'esprit lors de leur utilisation.


mise à jour : Voici comment jQuery le fait maintenant (2.2-stable) :

isNumeric: function(obj) {
    var realStringObj = obj && obj.toString();
    return !jQuery.isArray(obj) && (realStringObj - parseFloat(realStringObj) + 1) >= 0;
}

Mise à jour : Angulaire 4.3 :

export function isNumeric(value: any): boolean {
    return !isNaN(value - parseFloat(value));
}
2775
répondu CMS 2018-06-01 15:21:11

Arrrgh! N'écoutez pas l'expression régulière réponses. RegEx est dégueulasse pour ça, et je ne parle pas que de performance. Il est si facile de faire subtil, impossible de repérer les erreurs avec votre expression régulière.

si vous ne pouvez pas utiliser isNaN() , cela devrait fonctionner beaucoup mieux:

function IsNumeric(input)
{
    return (input - 0) == input && (''+input).trim().length > 0;
}

Voici comment ça marche:

l'expression (input - 0) force JavaScript à effectuer une coercition de type sur votre valeur d'entrée; il doit d'abord être interprétée comme un numéro pour l'opération de soustraction. Si cette conversion à un nombre échoue, l'expression résultera en NaN . Ce résultat numérique est ensuite comparé à la valeur originale que vous avez transmise. Puisque le côté gauche est maintenant numérique, la coercition de type est de nouveau utilisé. Maintenant que l'entrée des deux côtés a été forcée au même type à partir de la même valeur originale, vous penseriez qu'ils devraient toujours être les mêmes (toujours vrai). Cependant, il y a une règle spéciale qui dit que NaN n'est jamais égal à NaN , et donc une valeur qui ne peut pas être convertie en un nombre (et seules les valeurs qui ne peuvent pas être converties en nombres) résultera en faux.

la vérification de la longueur s'applique à un cas spécial où les cordes sont vides. Notez également qu'il tombe sur votre 0x89f test, mais c'est parce que dans de nombreux environnements, c'est un bon moyen de définir un nombre littéral. Si vous voulez attraper que le scénario vous pourriez ajouter une vérification supplémentaire. Encore mieux, si c'est votre raison de ne pas utiliser isNaN() alors il suffit d'envelopper votre propre fonction autour de isNaN() qui peut également faire le contrôle supplémentaire.

En résumé, si vous voulez savoir si une valeur peut être convertie en nombre, en fait on essaie de le convertir en nombre.


j'ai fait quelques recherches pour pourquoi une chaîne d'espace n'avait pas la sortie attendue, et je pense que je l'ai maintenant: une chaîne vide est forcée à 0 plutôt que NaN . Il suffit de couper la corde avant le contrôle de longueur va gérer ce cas.

exécuter les tests unitaires contre le nouveau code et il échoue seulement sur l'infini et les littérales booléennes, et le seul moment qui devrait être un problème est si vous générez du code (vraiment, qui taperait dans un littéral et vérifier si c'est numérique? Vous devriez savoir ), et ce serait un code étrange à générer.

mais, encore une fois, la seule raison d'utiliser ceci est si pour une raison quelconque vous devez éviter isNaN().

316
répondu Joel Coehoorn 2015-01-28 20:47:01

de Cette façon, semble bien fonctionner:

function IsNumeric(input){
    var RE = /^-{0,1}\d*\.{0,1}\d+$/;
    return (RE.test(input));
}

et de le tester:

// alert(TestIsNumeric());

function TestIsNumeric(){
    var results = ''
    results += (IsNumeric('-1')?"Pass":"Fail") + ": IsNumeric('-1') => true\n";
    results += (IsNumeric('-1.5')?"Pass":"Fail") + ": IsNumeric('-1.5') => true\n";
    results += (IsNumeric('0')?"Pass":"Fail") + ": IsNumeric('0') => true\n";
    results += (IsNumeric('0.42')?"Pass":"Fail") + ": IsNumeric('0.42') => true\n";
    results += (IsNumeric('.42')?"Pass":"Fail") + ": IsNumeric('.42') => true\n";
    results += (!IsNumeric('99,999')?"Pass":"Fail") + ": IsNumeric('99,999') => false\n";
    results += (!IsNumeric('0x89f')?"Pass":"Fail") + ": IsNumeric('0x89f') => false\n";
    results += (!IsNumeric('#abcdef')?"Pass":"Fail") + ": IsNumeric('#abcdef') => false\n";
    results += (!IsNumeric('1.2.3')?"Pass":"Fail") + ": IsNumeric('1.2.3') => false\n";
    results += (!IsNumeric('')?"Pass":"Fail") + ": IsNumeric('') => false\n";
    results += (!IsNumeric('blah')?"Pass":"Fail") + ": IsNumeric('blah') => false\n";

    return results;
}

j'ai emprunté ce regex de http://www.codetoad.com/javascript/isnumeric.asp . Explication:

/^ match beginning of string
-{0,1} optional negative sign
\d* optional digits
\.{0,1} optional decimal point
\d+ at least one digit
$/ match end of string
58
répondu Michael Haren 2008-08-20 14:22:56

Yahoo! UI utilise ceci:

isNumber: function(o) {
    return typeof o === 'number' && isFinite(o);
}
46
répondu camomileCase 2013-04-02 00:39:05
function IsNumeric(num) {
     return (num >=0 || num < 0);
}

cela fonctionne aussi pour les numéros de type 0x23.

44
répondu user189277 2012-06-16 13:01:37

la réponse acceptée a échoué à l'examen no 7 et je suppose que c'est parce que vous avez changé d'avis. Il s'agit donc d'une réponse à la réponse acceptée, avec laquelle j'avais des problèmes.

au cours de certains projets, j'ai eu besoin de valider certaines données et d'être aussi certain que possible qu'il s'agit d'une valeur numérique javascript qui peut être utilisé dans les opérations mathématiques.

jQuery, et quelques autres bibliothèques javascript incluent déjà une telle fonction, généralement appelée isNumeric . Il y a aussi un post sur stackoverflow qui a été largement accepté comme la réponse, la même routine générale que les bibliothèques mentionnées ci-dessus utilisent.

function isNumber(n) {
  return !isNaN(parseFloat(n)) && isFinite(n);
}

tout d'abord, le code ci-dessus retournerait true si l'argument était un tableau de longueur 1, et que cet élément simple était d'un type considéré comme numérique par la logique ci-dessus. À mon avis, si c'est un tableau puis son pas numérique.

pour alléger ce problème, j'ai ajouté un chèque pour réduire les tableaux de la logique

function isNumber(n) {
  return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n);
}

bien sûr, vous pouvez également utiliser Array.isArray , jquery $.isArray ou prototype Object.isArray au lieu de Object.prototype.toString.call(n) !== '[object Array]'

mon deuxième problème était que les chaînes hexadécimales entières négatives littérales ("- 0xA " - > -10) n'étaient pas comptées comme numériques. Cependant, les chaînes hexadécimales entières littérales positives ("0xA" -> 10) ont été traitées comme numériques. J'ai besoin des deux pour être valide numérique.

j'ai ensuite modifié la logique pour en tenir compte.

function isNumber(n) {
  return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(/^-/, ''));
}

si vous êtes inquiet au sujet de la création du regex chaque fois que la fonction est appelée alors vous pourriez La réécrire dans une fermeture, quelque chose comme ceci

var isNumber = (function () {
  var rx = /^-/;

  return function (n) {
      return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(rx, ''));
  };
}());

j'ai alors pris CMSs +30 cas d'essai et cloné le test sur jsfiddle ajouté mes cas d'essai supplémentaires et mon ci-dessus décrit solution.

il ne peut pas remplacer la réponse largement acceptée/utilisée, mais si c'est plus de ce que vous attendez comme résultats de votre fonction isnumérique alors espérons que ce sera d'une certaine aide.

EDIT: Comme l'a souligné Bergi , il y a d'autres objets qui pourraient être considérés comme des numériques, et il serait préférable d'indiquer que la liste noire. Dans cette optique, je voudrais ajouter quelques éléments aux critères.

je veux que ma fonction isnumérique ne considère que les nombres ou les chaînes

Avec cela à l'esprit, il serait préférable d'utiliser

function isNumber(n) {
  return (Object.prototype.toString.call(n) === '[object Number]' || Object.prototype.toString.call(n) === '[object String]') &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(/^-/, ''));
}

tester les solutions

var testHelper = function() {

  var testSuite = function() {
    test("Integer Literals", function() {
      ok(isNumber("-10"), "Negative integer string");
      ok(isNumber("0"), "Zero string");
      ok(isNumber("5"), "Positive integer string");
      ok(isNumber(-16), "Negative integer number");
      ok(isNumber(0), "Zero integer number");
      ok(isNumber(32), "Positive integer number");
      ok(isNumber("040"), "Octal integer literal string");
      ok(isNumber(0144), "Octal integer literal");
      ok(isNumber("-040"), "Negative Octal integer literal string");
      ok(isNumber(-0144), "Negative Octal integer literal");
      ok(isNumber("0xFF"), "Hexadecimal integer literal string");
      ok(isNumber(0xFFF), "Hexadecimal integer literal");
      ok(isNumber("-0xFF"), "Negative Hexadecimal integer literal string");
      ok(isNumber(-0xFFF), "Negative Hexadecimal integer literal");
    });

    test("Foating-Point Literals", function() {
      ok(isNumber("-1.6"), "Negative floating point string");
      ok(isNumber("4.536"), "Positive floating point string");
      ok(isNumber(-2.6), "Negative floating point number");
      ok(isNumber(3.1415), "Positive floating point number");
      ok(isNumber(8e5), "Exponential notation");
      ok(isNumber("123e-2"), "Exponential notation string");
    });

    test("Non-Numeric values", function() {
      equals(isNumber(""), false, "Empty string");
      equals(isNumber("        "), false, "Whitespace characters string");
      equals(isNumber("\t\t"), false, "Tab characters string");
      equals(isNumber("abcdefghijklm1234567890"), false, "Alphanumeric character string");
      equals(isNumber("xabcdefx"), false, "Non-numeric character string");
      equals(isNumber(true), false, "Boolean true literal");
      equals(isNumber(false), false, "Boolean false literal");
      equals(isNumber("bcfed5.2"), false, "Number with preceding non-numeric characters");
      equals(isNumber("7.2acdgs"), false, "Number with trailling non-numeric characters");
      equals(isNumber(undefined), false, "Undefined value");
      equals(isNumber(null), false, "Null value");
      equals(isNumber(NaN), false, "NaN value");
      equals(isNumber(Infinity), false, "Infinity primitive");
      equals(isNumber(Number.POSITIVE_INFINITY), false, "Positive Infinity");
      equals(isNumber(Number.NEGATIVE_INFINITY), false, "Negative Infinity");
      equals(isNumber(new Date(2009, 1, 1)), false, "Date object");
      equals(isNumber(new Object()), false, "Empty object");
      equals(isNumber(function() {}), false, "Instance of a function");
      equals(isNumber([]), false, "Empty Array");
      equals(isNumber(["-10"]), false, "Array Negative integer string");
      equals(isNumber(["0"]), false, "Array Zero string");
      equals(isNumber(["5"]), false, "Array Positive integer string");
      equals(isNumber([-16]), false, "Array Negative integer number");
      equals(isNumber([0]), false, "Array Zero integer number");
      equals(isNumber([32]), false, "Array Positive integer number");
      equals(isNumber(["040"]), false, "Array Octal integer literal string");
      equals(isNumber([0144]), false, "Array Octal integer literal");
      equals(isNumber(["-040"]), false, "Array Negative Octal integer literal string");
      equals(isNumber([-0144]), false, "Array Negative Octal integer literal");
      equals(isNumber(["0xFF"]), false, "Array Hexadecimal integer literal string");
      equals(isNumber([0xFFF]), false, "Array Hexadecimal integer literal");
      equals(isNumber(["-0xFF"]), false, "Array Negative Hexadecimal integer literal string");
      equals(isNumber([-0xFFF]), false, "Array Negative Hexadecimal integer literal");
      equals(isNumber([1, 2]), false, "Array with more than 1 Positive interger number");
      equals(isNumber([-1, -2]), false, "Array with more than 1 Negative interger number");
    });
  }

  var functionsToTest = [

    function(n) {
      return !isNaN(parseFloat(n)) && isFinite(n);
    },

    function(n) {
      return !isNaN(n) && !isNaN(parseFloat(n));
    },

    function(n) {
      return !isNaN((n));
    },

    function(n) {
      return !isNaN(parseFloat(n));
    },

    function(n) {
      return typeof(n) != "boolean" && !isNaN(n);
    },

    function(n) {
      return parseFloat(n) === Number(n);
    },

    function(n) {
      return parseInt(n) === Number(n);
    },

    function(n) {
      return !isNaN(Number(String(n)));
    },

    function(n) {
      return !isNaN(+('' + n));
    },

    function(n) {
      return (+n) == n;
    },

    function(n) {
      return n && /^-?\d+(\.\d+)?$/.test(n + '');
    },

    function(n) {
      return isFinite(Number(String(n)));
    },

    function(n) {
      return isFinite(String(n));
    },

    function(n) {
      return !isNaN(n) && !isNaN(parseFloat(n)) && isFinite(n);
    },

    function(n) {
      return parseFloat(n) == n;
    },

    function(n) {
      return (n - 0) == n && n.length > 0;
    },

    function(n) {
      return typeof n === 'number' && isFinite(n);
    },

    function(n) {
      return !Array.isArray(n) && !isNaN(parseFloat(n)) && isFinite(n.toString().replace(/^-/, ''));
    }

  ];


  // Examines the functionsToTest array, extracts the return statement of each function
  // and fills the toTest select element.
  var fillToTestSelect = function() {
    for (var i = 0; i < functionsToTest.length; i++) {
      var f = functionsToTest[i].toString();
      var option = /[\s\S]*return ([\s\S]*);/.exec(f)[1];
      $("#toTest").append('<option value="' + i + '">' + (i + 1) + '. ' + option + '</option>');
    }
  }

  var performTest = function(functionNumber) {
    reset(); // Reset previous test
    $("#tests").html(""); //Clean test results
    isNumber = functionsToTest[functionNumber]; // Override the isNumber global function with the one to test
    testSuite(); // Run the test

    // Get test results
    var totalFail = 0;
    var totalPass = 0;
    $("b.fail").each(function() {
      totalFail += Number($(this).html());
    });
    $("b.pass").each(function() {
      totalPass += Number($(this).html());
    });
    $("#testresult").html(totalFail + " of " + (totalFail + totalPass) + " test failed.");

    $("#banner").attr("class", "").addClass(totalFail > 0 ? "fail" : "pass");
  }

  return {
    performTest: performTest,
    fillToTestSelect: fillToTestSelect,
    testSuite: testSuite
  };
}();


$(document).ready(function() {
  testHelper.fillToTestSelect();
  testHelper.performTest(0);

  $("#toTest").change(function() {
    testHelper.performTest($(this).children(":selected").val());
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js" type="text/javascript"></script>
<script src="https://rawgit.com/Xotic750/testrunner-old/master/testrunner.js" type="text/javascript"></script>
<link href="https://rawgit.com/Xotic750/testrunner-old/master/testrunner.css" rel="stylesheet" type="text/css">
<h1>isNumber Test Cases</h1>

<h2 id="banner" class="pass"></h2>

<h2 id="userAgent">Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11</h2>

<div id="currentFunction"></div>

<div id="selectFunction">
  <label for="toTest" style="font-weight:bold; font-size:Large;">Select function to test:</label>
  <select id="toTest" name="toTest">
  </select>
</div>

<div id="testCode"></div>

<ol id="tests">
  <li class="pass">
    <strong>Integer Literals <b style="color:black;">(0, 10, 10)</b></strong>

    <ol style="display: none;">
      <li class="pass">Negative integer string</li>

      <li class="pass">Zero string</li>

      <li class="pass">Positive integer string</li>

      <li class="pass">Negative integer number</li>

      <li class="pass">Zero integer number</li>

      <li class="pass">Positive integer number</li>

      <li class="pass">Octal integer literal string</li>

      <li class="pass">Octal integer literal</li>

      <li class="pass">Hexadecimal integer literal string</li>

      <li class="pass">Hexadecimal integer literal</li>
    </ol>
  </li>

  <li class="pass">
    <strong>Foating-Point Literals <b style="color:black;">(0, 6, 6)</b></strong>

    <ol style="display: none;">
      <li class="pass">Negative floating point string</li>

      <li class="pass">Positive floating point string</li>

      <li class="pass">Negative floating point number</li>

      <li class="pass">Positive floating point number</li>

      <li class="pass">Exponential notation</li>

      <li class="pass">Exponential notation string</li>
    </ol>
  </li>

  <li class="pass">
    <strong>Non-Numeric values <b style="color:black;">(0, 18, 18)</b></strong>

    <ol style="display: none;">
      <li class="pass">Empty string: false</li>

      <li class="pass">Whitespace characters string: false</li>

      <li class="pass">Tab characters string: false</li>

      <li class="pass">Alphanumeric character string: false</li>

      <li class="pass">Non-numeric character string: false</li>

      <li class="pass">Boolean true literal: false</li>

      <li class="pass">Boolean false literal: false</li>

      <li class="pass">Number with preceding non-numeric characters: false</li>

      <li class="pass">Number with trailling non-numeric characters: false</li>

      <li class="pass">Undefined value: false</li>

      <li class="pass">Null value: false</li>

      <li class="pass">NaN value: false</li>

      <li class="pass">Infinity primitive: false</li>

      <li class="pass">Positive Infinity: false</li>

      <li class="pass">Negative Infinity: false</li>

      <li class="pass">Date object: false</li>

      <li class="pass">Empty object: false</li>

      <li class="pass">Instance of a function: false</li>
    </ol>
  </li>
</ol>

<div id="main">
  This page contains tests for a set of isNumber functions. To see them, take a look at the source.
</div>

<div>
  <p class="result">Tests completed in 0 milliseconds.
    <br>0 tests of 0 failed.</p>
</div>
37
répondu Xotic750 2018-01-05 12:56:31

Ouais, le intégré isNaN(object) sera beaucoup plus rapide que n'importe quel parsing regex, parce qu'il est intégré et compilé, au lieu d'être interprété à la volée.

Bien que les résultats sont quelque peu différents de ce que vous cherchez ( essayer ):

                                              // IS NUMERIC
document.write(!isNaN('-1') + "<br />");      // true
document.write(!isNaN('-1.5') + "<br />");    // true
document.write(!isNaN('0') + "<br />");       // true
document.write(!isNaN('0.42') + "<br />");    // true
document.write(!isNaN('.42') + "<br />");     // true
document.write(!isNaN('99,999') + "<br />");  // false
document.write(!isNaN('0x89f') + "<br />");   // true
document.write(!isNaN('#abcdef') + "<br />"); // false
document.write(!isNaN('1.2.3') + "<br />");   // false
document.write(!isNaN('') + "<br />");        // true
document.write(!isNaN('blah') + "<br />");    // false
30
répondu travis 2013-08-08 14:39:20

depuis jQuery 1.7, vous pouvez utiliser jQuery.isNumeric() :

$.isNumeric('-1');      // true
$.isNumeric('-1.5');    // true
$.isNumeric('0');       // true
$.isNumeric('0.42');    // true
$.isNumeric('.42');     // true
$.isNumeric('0x89f');   // true (valid hexa number)
$.isNumeric('99,999');  // false
$.isNumeric('#abcdef'); // false
$.isNumeric('1.2.3');   // false
$.isNumeric('');        // false
$.isNumeric('blah');    // false

notez que contrairement à ce que vous avez dit, 0x89f est un nombre valide (hexa)

14
répondu Kuf 2013-02-18 09:01:43

utiliser la fonction isNaN . Je crois que si vous testez pour !isNaN(yourstringhere) cela fonctionne très bien pour l'une de ces situations.

14
répondu bubbassauro 2016-02-10 16:19:51

Il peut être fait sans RegExp

function IsNumeric(data){
    return parseFloat(data)==data;
}
10
répondu Aquatic 2008-08-22 15:08:05

je me rends compte que la question originale ne mentionnait pas jQuery, mais si vous utilisez jQuery, vous pouvez le faire:

$.isNumeric(val)

Simple.

https://api.jquery.com/jQuery.isNumeric / (à partir de jQuery 1.7)

5
répondu Sean the Bean 2014-01-13 16:42:50

si Je ne me trompe pas, cela devrait correspondre à n'importe quelle valeur valide du nombre JavaScript, excluant les constantes ( Infinity , NaN ) et les opérateurs de signe + / - (parce qu'ils ne font pas réellement partie du nombre en ce qui me concerne, ils sont des opérateurs séparés):

j'en avais besoin pour un tokenizer, où envoyer le numéro à JavaScript pour évaluation n'était pas une option... Ce n'est certainement pas la plus courte expression régulière possible, mais je je crois qu'il saisit toutes les subtilités de la syntaxe des nombres de JavaScript.

/^(?:(?:(?:[1-9]\d*|\d)\.\d*|(?:[1-9]\d*|\d)?\.\d+|(?:[1-9]\d*|\d)) 
(?:[e]\d+)?|0[0-7]+|0x[0-9a-f]+)$/i

les numéros valides comprendraient:

 - 0
 - 00
 - 01
 - 10
 - 0e1
 - 0e01
 - .0
 - 0.
 - .0e1
 - 0.e1
 - 0.e00
 - 0xf
 - 0Xf

les numéros invalides seraient

 - 00e1
 - 01e1
 - 00.0
 - 00x0
 - .
 - .e0
5
répondu Jonathan Spooner 2016-02-10 16:14:12
return (input - 0) == input && input.length > 0;

n'a pas marché pour moi. Quand j'ai mis une alerte et testé, input.length était undefined . Je pense qu'il n'y a pas de propriété pour vérifier la longueur entière. Donc ce que j'ai fait c'était

var temp = '' + input;
return (input - 0) == input && temp.length > 0;

ça a bien marché.

5
répondu jayakumar 2018-01-05 13:04:36

Pour moi, c'est la meilleure façon:

isNumber : function(v){
   return typeof v === 'number' && isFinite(v);
}
4
répondu InsertNameHere 2010-05-28 11:30:26

une valeur entière peut être vérifiée par:

function isNumeric(value) {
    var bool = isNaN(+value));
    bool = bool || (value.indexOf('.') != -1);
    bool = bool || (value.indexOf(",") != -1);
    return !bool;
};

c'est plus facile et plus rapide! Tous les tests sont vérifiés!

4
répondu solidarius 2013-01-06 18:36:05

Voici une version améliorée (probablement la plus rapide) que j'utilise au lieu de la variante exacte de jQuery, je ne sais vraiment pas pourquoi ils n'utilisent pas celle-ci:

function isNumeric(val) {
    return !isNaN(+val) && isFinite(val);
}

l'inconvénient de la version de jQuery est que si vous passez une chaîne de caractères avec des chiffres et des lettres traînantes comme "123abc" le parseFloat | parseInt extraira la fraction numérique et retournera 123, mais, le deuxième garde isFinite échouera de toute façon. Avec le unaire + opérateur il mourra sur la toute première garde depuis + jette NaN pour de tels hybrides :) Un peu de performance, mais je pense que c'est un gain sémantique.

4
répondu Arman McHitarian 2013-05-20 16:48:18

quelques essais pour ajouter:

IsNumeric('01.05') => false
IsNumeric('1.') => false
IsNumeric('.') => false

j'ai trouvé ceci:

function IsNumeric(input) {
    return /^-?(0|[1-9]\d*|(?=\.))(\.\d+)?$/.test(input);
}

la solution couvre:

  • un signe négatif facultatif au début
  • un seul zéro, ou un ou plusieurs chiffres ne commençant pas par 0, ou rien tant qu'une période Suit
  • période suivie d'un ou de plusieurs nombres
3
répondu pottedmeat 2011-05-25 09:25:24

Ma solution", 151920920"

function isNumeric(input) {
    var number = /^\-{0,1}(?:[0-9]+){0,1}(?:\.[0-9]+){0,1}$/i;
    var regex = RegExp(number);
    return regex.test(input) && input.length>0;
}

il semble fonctionner dans toutes les situations, mais je pourrais me tromper.

3
répondu Manusoftar 2011-05-25 09:35:22

ça devrait marcher. Certaines des fonctions fournies ici sont défectueux, devrait également être plus rapide que toute autre fonction ici.

        function isNumeric(n)
        {
            var n2 = n;
            n = parseFloat(n);
            return (n!='NaN' && n2==n);
        }

expliquée:

crée une copie de lui-même, puis convertit le nombre en flottant, puis se compare avec le nombre original, s'il s'agit encore d'un nombre (entier ou flottant) , et correspond au nombre original, ce qui signifie qu'il s'agit bien d'un nombre.

il fonctionne avec Numérique les chaînes en tant que bien comme de simples numéros. Ne fonctionne pas avec les nombres hexadécimaux.

avertissement: utiliser à vos risques et périls, sans garantie.

3
répondu user532188 2013-08-07 21:59:27

j'aimerais ajouter ce qui suit:

1. IsNumeric('0x89f') => true
2. IsNumeric('075') => true

les nombres hexadécimaux positifs commencent par 0x et les nombres hexadécimaux négatifs commencent par -0x . Les nombres d'oct positifs commencent par 0 et les nombres d'oct négatifs commencent par -0 . Celui-ci prend la plupart de ce qui a déjà été mentionné en considération, mais comprend les nombres hexadécimaux et octal, négatif scientifique, L'infini et a enlevé décimal scientifique ( 4e3.2 n'est pas valide).

function IsNumeric(input){
  var RE = /^-?(0|INF|(0[1-7][0-7]*)|(0x[0-9a-fA-F]+)|((0|[1-9][0-9]*|(?=[\.,]))([\.,][0-9]+)?([eE]-?\d+)?))$/;
  return (RE.test(input));
}
3
répondu Marius 2018-01-05 13:02:03

j'utilise une solution plus simple:

function isNumber(num) {
    return parseFloat(num).toString() == num
}
2
répondu Ali Gonabadi 2012-06-16 12:25:25

aucune des réponses ne retourne false pour des cordes vides, un correctif pour cela...

function is_numeric(n)
{
 return (n != '' && !isNaN(parseFloat(n)) && isFinite(n));
}
2
répondu John 2016-02-10 16:13:18

réponse de @CMS : votre snippet a échoué sur les cas de blancs espace sur ma machine en utilisant nodejs. Donc je l'ai combiné avec @joel réponse de la manière suivante:

is_float = function(v) {
    return !isNaN(v) && isFinite(v) &&
        (typeof(v) == 'number' || v.replace(/^\s+|\s+$/g, '').length > 0);
}

je unittested avec les cas qui sont des flotteurs:

var t = [
        0,
        1.2123,
        '0',
        '2123.4',
        -1,
        '-1',
        -123.423,
        '-123.432',
        07,
        0xad,
        '07',
        '0xad'
    ];

et les boîtiers qui ne sont pas des flotteurs (y compris les espaces vides et les objets / matrices):

    var t = [
        'hallo',
        [],
        {},
        'jklsd0',
        '',
        "\t",
        "\n",
        ' '
    ];

Tout fonctionne comme prévu ici. Peut-être cela peut vous aider.

le code source complet pour cela peut être trouvé ici .

1
répondu Phil 2017-05-23 12:34:53

ce qui suit semble fonctionner très bien dans de nombreux cas:

function isNumeric(num) {
    return (num > 0 || num === 0 || num === '0' || num < 0) && num !== true && isFinite(num);
}

C'est construit sur cette réponse (qui est pour répondre à cette question trop): https://stackoverflow.com/a/1561597/1985601

1
répondu daniel1426 2017-05-23 12:18:30

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.

function isDecimal(x) {
  return '' + x === '' + +x;
}

function isInteger(x) {
  return '' + x === '' + parseInt(x);
}

le isDecimal passe avec succès l'essai suivant:

function testIsNumber(f) {
  return f('-1') && f('-1.5') && f('0') && f('0.42')
    && !f('.42') && !f('99,999') && !f('0x89f')
    && !f('#abcdef') && !f('1.2.3') && !f('') && !f('blah');
}

l'idée ici est que chaque nombre ou entier a une chaîne "canonique" toute représentation non canonique doit être rejetée. Donc, nous moulons vers un nombre et en arrière, et voyons si le résultat est la chaîne originale.

Si ces fonctions sont utiles pour vous dépend du cas d'utilisation. Une caractéristique est que chaînes distinctes représentent des nombres distincts (si les deux passent le test isNumber() ).

ceci est pertinent par exemple pour les nombres comme noms de propriétés d'objet.

var obj = {};
obj['4'] = 'canonical 4';
obj['04'] = 'alias of 4';
obj[4];  // prints 'canonical 4' to the console.
1
répondu donquixote 2015-07-15 00:17:22

knockoutJs Inbuild bibliothèque de fonctions de validation

en l'étendant le champ obtenir validé

1) numéro

self.number = ko.observable(numberValue) .étendre ({ numéro: vrai}) ;

TestCase

numberValue = '0.0'    --> true
numberValue = '0'      --> true
numberValue = '25'     --> true
numberValue = '-1'     --> true
numberValue = '-3.5'   --> true
numberValue = '11.112' --> true
numberValue = '0x89f'  --> false
numberValue = ''       --> false
numberValue = 'sfsd'   --> false
numberValue = 'dg##$'  --> false

2) chiffre 151990920"

self.number = ko.observable(numberValue) .étendre ({ chiffre: vrai}) ;

TestCase

numberValue = '0'      --> true
numberValue = '25'     --> true
numberValue = '0.0'    --> false
numberValue = '-1'     --> false
numberValue = '-3.5'   --> false
numberValue = '11.112' --> false
numberValue = '0x89f'  --> false
numberValue = ''       --> false
numberValue = 'sfsd'   --> false
numberValue = 'dg##$'  --> false

3) min. et max. 151990920"

self.number = ko.observable(numberValue) .prolonger ({ min: 5}).extension (max.: 10}) ;

cette zone accepte la valeur entre 5 et 10 seulement

TestCase

numberValue = '5'    --> true
numberValue = '6'    --> true
numberValue = '6.5'  --> true
numberValue = '9'    --> true
numberValue = '11'   --> false
numberValue = '0'    --> false
numberValue = ''    --> false
1
répondu nav0611 2016-02-10 16:17:14

pour vérifier si une variable contient un nombre valide et non juste une corde qui ressemble à un nombre, Number.isFinite(value) peut être utilisé.

Cela fait partie de la langue depuis ES2015

exemples:

Number.isFinite(Infinity)   // false
Number.isFinite(NaN)        // false
Number.isFinite(-Infinity)  // false

Number.isFinite(0)          // true
Number.isFinite(2e64)       // true

Number.isFinite('0')        // false
Number.isFinite(null)       // false
1
répondu adius 2016-04-12 20:00:46

vous pouvez minimiser cette fonction de beaucoup de manière, et vous pouvez également l'implémenter avec un regex personnalisé pour les valeurs négatives ou des graphiques personnalisés:

$('.number').on('input',function(){
    var n=$(this).val().replace(/ /g,'').replace(/\D/g,'');
    if (!$.isNumeric(n))
        $(this).val(n.slice(0, -1))
    else
        $(this).val(n)
});
1
répondu Vixed 2017-02-23 15:16:43
function inNumeric(n){
   return Number(n).toString() === n;
}

si n est numérique Number(n) retournera la valeur numérique et toString() la retournera à une chaîne. Mais si n n'est pas numérique Number(n) retournera NaN ainsi il ne sera pas correspondre à l'original n

1
répondu chrmcpn 2017-12-18 21:28:25