Validar números decimales en JavaScript-IsNumeric()


¿Cuál es la forma más limpia y efectiva de validar números decimales en JavaScript?

Puntos de bonificación para:

  1. Claridad. La solución debe ser limpia y simple.
  2. Multiplataforma.

Casos de prueba:

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
Author: Michael Haren, 2008-08-20

30 answers

@La respuesta de Joel está bastante cerca, pero fallará en los siguientes casos:

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

Hace algún tiempo tuve que implementar una función IsNumeric, para averiguar si una variable contenía un valor numérico, independientemente de su tipo, podría ser un String que contiene un valor numérico (tuve que considerar también la notación exponencial, etc.), un objeto Number, prácticamente cualquier cosa podría pasarse a esa función, no podía hacer ningún tipo de suposiciones, teniendo cuidado de la coerción tipo (por ejemplo. +true == 1; pero true no debe considerarse como "numeric").

Creo que vale la pena compartir este conjunto de +30 pruebas unitarias hecho a numerosas implementaciones de funciones, y también compartir la que pasa todas mis pruebas:

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

P.d. isNaN & isFinite tiene un comportamiento confuso debido a la conversión forzada a número. En ES6, Número.isNaN & Número.isFinite solucionaría estos problemas. Tenga eso en cuenta cuando los use.


Actualización : Así es como jQuery lo hace ahora (2.2-stable):

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

Actualización : Angular 4.3:

export function isNumeric(value: any): boolean {
    return !isNaN(value - parseFloat(value));
}
 2775
Author: CMS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-01 15:21:11

Arrrgh! No escuches las respuestas de la expresión regular. RegEx es asqueroso para esto, y no estoy hablando solo de rendimiento. Es tan fácil cometer errores sutiles e imposibles de detectar con tu expresión regular.

Si no puedes usar isNaN(), esto debería funcionar mucho mejor:

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

Así es como funciona:

La expresión (input - 0) obliga a JavaScript a hacer coerción de tipo sobre su valor de entrada; primero debe interpretarse como un número para la operación de resta. Si esa conversión a un número falla, la expresión resultará en NaN. Este resultado numérico se compara con el valor original que pasó. Dado que el lado izquierdo ahora es numérico, el tipo coerción se usa de nuevo. Ahora que la entrada de ambos lados fue coaccionada al mismo tipo desde el mismo valor original, pensarías que siempre deberían ser los mismos (siempre verdaderos). Sin embargo, hay una regla especial que dice que NaN nunca es igual a NaN, por lo que un valor que no se puede convertir a un número (y solo los valores que no se pueden convertir en números) dará como resultado false.

La comprobación de la longitud es para un caso especial que involucra cadenas vacías. También tenga en cuenta que cae en su prueba 0x89f, pero eso es porque en muchos entornos que es una buena manera de definir un número literal. Si desea capturar ese escenario específico, podría agregar una verificación adicional. Aún mejor, si esa es su razón para no usar isNaN() entonces simplemente envuelva su propia función alrededor de isNaN() que también puede hacer la comprobación adicional.

En resumen, si desea saber si un valor se puede convertir en un número, intente convertirlo en un número.


Regresé e hice algunas investigaciones para por qué una cadena de espacios en blanco no tenía la salida esperada, y creo que lo entiendo ahora: una cadena vacía se coacciona a 0 en lugar de NaN. Simplemente recortar la cuerda antes de la comprobación de longitud manejará este caso.

Ejecutando la unidad prueba contra el nuevo código y solo falla en los literales infinity y boolean, y la única vez que debería ser un problema es si estás generando código (realmente, ¿quién escribiría un literal y verificaría si es numérico? Deberías saber), y eso sería algún código extraño para generar.

Pero, de nuevo, la única razón para usar esto es si por alguna razón tienes que evitar isNaN().

 316
Author: Joel Coehoorn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-28 20:47:01

Esta manera parece funcionar bien:

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

Y para probarlo:

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

Tomé prestada esa expresión regular de http://www.codetoad.com/javascript/isnumeric.asp . Explicación:

/^ 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
Author: Michael Haren,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-20 14:22:56

Yahoo! UI usa esto:

isNumber: function(o) {
    return typeof o === 'number' && isFinite(o);
}
 46
Author: camomileCase,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-02 00:39:05
function IsNumeric(num) {
     return (num >=0 || num < 0);
}

Esto también funciona para números de tipo 0x23.

 44
Author: user189277,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-16 13:01:37

La respuesta aceptada falló en tu examen #7 y supongo que es porque cambiaste de opinión. Así que esta es una respuesta a la respuesta aceptada, con la que tuve problemas.

Durante algunos proyectos he necesitado validar algunos datos y estar lo más seguro posible de que es un valor numérico de javascript que se puede usar en operaciones matemáticas.

JQuery, y algunas otras bibliotecas javascript ya incluyen tal función, generalmente llamada isNumeric. También hay un post en stackoverflow que ha sido ampliamente aceptado como la respuesta, la misma rutina general que las bibliotecas antes mencionadas están utilizando.

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

Primero, el código anterior devolvería true si el argumento era un array de longitud 1, y ese único elemento era de un tipo considerado numérico por la lógica anterior. En mi opinión, si es un array entonces no es numérico.

Para aliviar este problema, agregué una comprobación para descontar matrices de la lógica

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

Por supuesto, usted podría también use Array.isArray, jquery $.isArray o prototype Object.isArray en lugar de Object.prototype.toString.call(n) !== '[object Array]'

Mi segundo problema fue que las cadenas literales de enteros hexadecimales negativos ("-0xA" -> -10) no se contaban como numéricas. Sin embargo, las cadenas literales de enteros hexadecimales positivos ("0xA" -> 10) se trataron como numéricas. Necesitaba que ambos fueran numéricos válidos.

Entonces modifiqué la lógica para tener esto en cuenta.

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

Si está preocupado por la creación de la expresión regular cada vez que se llama a la función entonces usted podría reescribirlo dentro de un cierre, algo como esto

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

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

Luego tomé CMSs +30 casos de prueba y cloné la prueba en jsfiddle agregué mis casos de prueba adicionales y mi solución descrita anteriormente.

Puede que no reemplace la respuesta ampliamente aceptada/utilizada, pero si esto es más de lo que espera como resultado de su función isnumérica, entonces esperemos que esto sea de alguna ayuda.

EDITAR: Como señaló Bergi, hay otros objetos posibles que podrían considerarse numéricos y sería mejor incluir una lista blanca que una lista negra. Con esto en mente, añadiría a los criterios.

Quiero que mi función isnumérica considere solo Números o Cadenas

Con esto en mente, sería mejor usar

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(/^-/, ''));
}

Probar las soluciones

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
Author: Xotic750,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-05 12:56:31

Sí, el incorporado isNaN(object) será mucho más rápido que cualquier análisis de expresiones regulares, porque está integrado y compilado, en lugar de interpretado sobre la marcha.

Aunque los resultados son algo diferentes a lo que estás buscando (pruébalo):

                                              // 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
Author: travis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-08 14:39:20

Desde jQuery 1.7, puede utilizar 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

Solo tenga en cuenta que a diferencia de lo que dijo, 0x89f es un número válido (hexa)

 14
Author: Kuf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-18 09:01:43

Utilice la función isNaN. Creo que si pruebas !isNaN(yourstringhere) funciona bien para cualquiera de estas situaciones.

 14
Author: bubbassauro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-10 16:19:51

Se puede hacer sin RegExp como

function IsNumeric(data){
    return parseFloat(data)==data;
}
 10
Author: Aquatic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-22 15:08:05

Me doy cuenta de que la pregunta original no mencionaba jQuery, pero si usa jQuery, puede hacer:

$.isNumeric(val)

Simple.

Https://api.jquery.com/jQuery.isNumeric/ (a partir de jQuery 1.7)

 5
Author: Sean the Bean,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-13 16:42:50

Si no me equivoco, esto debería coincidir con cualquier valor de número JavaScript válido, excluyendo las constantes (Infinity, NaN) y los operadores de signo+/- (debido a que en realidad no son parte del número en lo que a mí respecta, son operadores separados):

Necesitaba esto para un tokenizador, donde enviar el número a JavaScript para su evaluación no era una opción... Definitivamente no es la expresión regular más corta posible, pero creo que captura todas las sutilezas más finas de JavaScript sintaxis numérica.

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

Los números válidos incluirían:

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

Los números no válidos serían

 - 00e1
 - 01e1
 - 00.0
 - 00x0
 - .
 - .e0
 5
Author: Jonathan Spooner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-10 16:14:12
return (input - 0) == input && input.length > 0;

No funcionó para mí. Cuando puse una alerta y probé, input.length fue undefined. Creo que no hay ninguna propiedad para comprobar la longitud del entero. Así que lo que hice fue

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

Funcionó bien.

 5
Author: jayakumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-05 13:04:36

Para mí, este es el mejor camino:

isNumber : function(v){
   return typeof v === 'number' && isFinite(v);
}
 4
Author: InsertNameHere,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-28 11:30:26

Un valor entero puede ser verificado por:

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

De esta manera es más fácil y más rápido! Todas las pruebas están comprobadas!

 4
Author: solidarius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-06 18:36:05

Aquí hay una versión mejorada de lil bit (probablemente la forma más rápida que hay) que uso en lugar de la variante exacta de jQuery, realmente no sé por qué no usan esta:

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

La desventaja de la versión de jQuery es que si pasa una cadena con números iniciales y letras finales como "123abc" el parseFloat | parseInt extraerá la fracción numérica y devolverá 123, PERO el segundo guardia isFinite fallará de todos modos. Con el operador unario + morirá en la primera guardia desde + lanza NaN para tales híbridos :) Un poco de rendimiento, pero creo que una sólida ganancia semántica.

 4
Author: Arman McHitarian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-20 16:48:18

El único problema que tuve con la respuesta de @CMS es la exclusión de NaN e Infinito, que son números útiles para muchas situaciones. Una forma de comprobar NaN es comprobar los valores numéricos que no se igualan a sí mismos, NaN != NaN! Así que hay realmente 3 pruebas que le gustaría tratar ...

function isNumber(n) {
  n = parseFloat(n);
  return !isNaN(n) || n != n;
}
function isFiniteNumber(n) {
  n = parseFloat(n);
  return !isNaN(n) && isFinite(n);
}    
function isComparableNumber(n) {
  n = parseFloat(n);
  return (n >=0 || n < 0);
}

isFiniteNumber('NaN')
false
isFiniteNumber('OxFF')
true
isNumber('NaN')
true
isNumber(1/0-1/0)
true
isComparableNumber('NaN')
false
isComparableNumber('Infinity')
true

Mi isComparableNumber está bastante cerca de otra respuesta elegante , pero maneja representaciones hexadecimales y otras cadenas de números.

 4
Author: hobs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-05 13:03:22

Un par de pruebas para agregar:

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

Se me ocurrió esto:

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

La solución cubre:

  • Un signo negativo opcional al principio
  • Un solo cero, o uno o más dígitos que no comiencen con 0, o nada siempre que siga un punto
  • Un punto que es seguido por 1 o más números
 3
Author: pottedmeat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-25 09:25:24

Mi solución,

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

Parece funcionar en cada situación, pero podría estar equivocado.

 3
Author: Manusoftar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-25 09:35:22

Esto debería funcionar. Algunas de las funciones proporcionadas aquí son defectuosas, también deben ser más rápidas que cualquier otra función aquí.

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

Explicado:

Crea una copia de sí mismo, luego convierte el número en flotante, luego se compara con el número original, si todavía es un número, (ya sea entero o flotante) , y coincide con el número original, eso significa que es de hecho un número.

Funciona tanto con cadenas numéricas como con números simples. No funciona con hexadecimal numero.

Advertencia: uso bajo su propio riesgo, sin garantías.

 3
Author: user532188,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-07 21:59:27

Me gustaría añadir lo siguiente:

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

Los números hexadecimales positivos comienzan con 0x y los números hexadecimales negativos comienzan con -0x. Los números oct positivos comienzan con 0 y los números oct negativos comienzan con -0. Este toma la mayor parte de lo que ya se ha mencionado en consideración, pero incluye números hexadecimales y octales, científicos negativos, Infinitos y ha eliminado el decimal científico (4e3.2 no es válido).

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
Author: Marius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-05 13:02:03

Estoy usando una solución más simple:

function isNumber(num) {
    return parseFloat(num).toString() == num
}
 2
Author: Ali Gonabadi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-16 12:25:25

Ninguna de las respuestas devuelve false para cadenas vacías, una solución para eso...

function is_numeric(n)
{
 return (n != '' && !isNaN(parseFloat(n)) && isFinite(n));
}
 2
Author: John,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-10 16:13:18

@Respuesta de CMS : Su fragmento falló en casos de espacios en blanco en mi máquina usando nodejs. Así que lo combiné con La respuesta de@joel a lo siguiente:

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

Lo unittested con los casos que son flotadores:

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

Y aquellos casos que no son flotadores (incluyendo espacios en blanco vacíos y objetos / matrices):

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

Todo funciona como se espera aquí. Tal vez esto ayude.

El código fuente completo para esto se puede encontrar aquí.

 1
Author: Phil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:53

Lo siguiente parece funcionar bien para muchos casos:

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

Esto se construye sobre esta respuesta (que también es para esta respuesta): https://stackoverflow.com/a/1561597/1985601

 1
Author: daniel1426,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:18:30

Me doy cuenta de que esto ha sido respondido muchas veces, pero el siguiente es un candidato decente que puede ser útil en algunos escenarios.

Debe señalarse que supone que".42 'no es un número, y' 4.'no es un número, por lo que esto debe tenerse en cuenta.

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

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

El isDecimal pasa la siguiente prueba:

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

La idea aquí es que cada número o entero tiene una representación de cadena "canónica", y cada representación no canónica debe ser rechazada. Así que cast a un número y hacia atrás, y ver si el resultado es la cadena original.

Si estas funciones son útiles para usted depende del caso de uso. Una característica es que cadenas distintas representan números distintos (si ambas pasan la prueba isNumber()).

Esto es relevante, por ejemplo, para los números como nombres de propiedad de objeto.

var obj = {};
obj['4'] = 'canonical 4';
obj['04'] = 'alias of 4';
obj[4];  // prints 'canonical 4' to the console.
 1
Author: donquixote,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-15 00:17:22

Funciones de validación de la biblioteca incorporada de KnockoutJS

Extendiéndolo el campo se valida

1) número

self.number = ko.observable(numberValue).extender ({ número: verdadero});

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) dígito

self.number = ko.observable(numberValue).extend ({digit: true});

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 y max

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

Este campo acepta valor entre 5 y 10 solamente

TestCase

numberValue = '5'    --> true
numberValue = '6'    --> true
numberValue = '6.5'  --> true
numberValue = '9'    --> true
numberValue = '11'   --> false
numberValue = '0'    --> false
numberValue = ''    --> false
 1
Author: nav0611,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-10 16:17:14

Para comprobar si una variable contiene un número válido y no sólo una cadena que se parece a un número, Number.isFinite(value) puede utilizarse.

Esto es parte del lenguaje ya que ES2015

Ejemplos:

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
Author: adius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-12 20:00:46

Puede minimizar esta función de muchas maneras, y también puede implementarla con una expresión regular personalizada para valores negativos o gráficos personalizados:

$('.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
Author: Vixed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-23 15:16:43
function inNumeric(n){
   return Number(n).toString() === n;
}

Si n es numérico Number(n) devolverá el valor numérico y toString() lo volverá a una cadena. Pero si n no es numérico Number(n) devolverá {[4] } por lo que no coincidirá con el original n

 1
Author: chrmcpn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-18 21:28:25