Pregunta

¿Cuál es el más limpio, el camino más eficaz para validar números decimales en JavaScript?

Puntos de bonificación para:

  1. La claridad.La solución debe estar limpio y simple.
  2. De la cruz-plataforma.

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
¿Fue útil?

Solución

@Joel respuesta está bastante cerca, pero se producirá 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 un IsNumeric función para averiguar si una variable contiene un valor numérico, independientemente de su tipo, podría ser una String contiene un valor numérico (tuve que considerar también la notación exponencial, etc.), un Number objeto, prácticamente cualquier cosa puede ser pasado a la función, no podía hacer ningún tipo de supuestos, teniendo cuidado de tipo de coerción (por ejemplo. +true == 1; pero true no debe ser considerado como "numeric").

Creo que vale la pena compartir este conjunto de +30 unidad de pruebas hizo numerosas implementaciones de función, y también compartir el que pasa todas mis pruebas:

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

P. S. isNaN & isFinite tienen un comportamiento confuso debido a la conversión forzosa al número.En ES6, Número.isNaN & Número.isFinite iba a solucionar estos problemas.Mantenga esto en mente cuando se usen.


Actualización : He aquí cómo jQuery hace ahora (2.2-estable):

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

Otros consejos

Arrrgh!No escuchar a la expresión regular las respuestas.RegEx es repulsivo para esto, y no estoy hablando solo de rendimiento.Es tan fácil hacer sutiles, imposible para detectar los errores con la expresión regular.

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

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

He aquí cómo funciona:

El (input - 0) la expresión de las fuerzas de JavaScript para hacer el tipo de coerción sobre su valor de entrada;primero debe ser interpretado como un número para la operación de resta.Si que la conversión a un número de error, la expresión resultará en NaN.Este numérico el resultado es comparado con el valor original que se ha pasado.Desde el lado izquierdo es ahora numérico, tipo de coacción se utiliza de nuevo.Ahora que la entrada de ambos lados fue coaccionado para el mismo tipo de el mismo valor original, se podría pensar que debe ser siempre el mismo (siempre cierto).Sin embargo, hay una regla especial que dice NaN nunca es igual a NaN, y así, un valor que no puede ser convertida a un número (y sólo los valores que no pueden ser convertidos a números) el resultado será falso.

La verificación de la longitud es un caso especial que implican cadenas vacías.Tenga en cuenta también que cae en su 0x89f prueba, pero eso es porque en muchos entornos en los que es una buena manera de definir un número literal.Si quieres coger esa situación específica en la que se podría añadir una comprobación adicional.Mejor aún, si esa es tu razón para no usar isNaN() a continuación, sólo envolver su propia función isNaN() que también puede hacer la comprobación adicional.

En resumen, si quieres saber si un valor se puede convertir en un número, en realidad se trata de convertir a un número.


Fui y hice un poco de investigación para por qué un espacio en blanco de la cadena no tienen el resultado esperado, y creo que lo tengo ahora:una cadena vacía es obligada a 0 en lugar de NaN.Simplemente el recorte de la cadena antes de la comprobación de la longitud va a manejar este caso.

Ejecutar las pruebas unitarias contra el nuevo código, en la que sólo se presenta en el infinito y literales booleanos, y la única vez que debe ser un problema si usted es la generación de código (realmente, que tendría que escribir en un literal y comprobar si es numérico?Usted debe saber), y que sería algún tipo de código para generar.

Pero, de nuevo, la única razón por la que cada vez el uso de esto es que si por alguna razón usted tiene que evitar isNaN().

De esta manera parece que funciona bien:

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

Y para ponerlo a prueba:

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

Yo pedí que regex 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

Yahoo!Interfaz de usuario usa este:

isNumber: function(o) {
    return typeof o === 'number' && isFinite(o);
}
function IsNumeric(num) {
     return (num >=0 || num < 0);
}

Esto funciona para 0x23 tipo de números.

El aceptó responder fallado en su prueba #7 y me imagino que es porque ha cambiado de opinión.Así que esta es una respuesta a la aceptación de la respuesta, con la que tuve problemas.

Durante algunos proyectos que he necesitado para validar algunos datos y ser tan seguro como sea posible de que se trata de un javascript valor numérico que puede ser utilizado en operaciones matemáticas.

jQuery, y algunas otras bibliotecas de javascript ya incluyen una función de este tipo, generalmente se llama isNumeric.También hay un post en stackoverflow que ha sido ampliamente aceptada como la respuesta, la misma rutina que el mencionado bibliotecas están usando.

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

En primer lugar, el código anterior devolverá true si el argumento es una matriz de longitud 1, y que el único elemento de un tipo considerado como numérico por la lógica anterior.En mi opinión, si es una matriz, entonces no es numérico.

Para paliar este problema, he añadido un cheque descuento de matrices a partir de la lógica

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

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

Mi segunda cuestión es que Negativo entero Hexadecimal cadenas literales ("-0xA" -> -10) no se contó como numérico.Sin embargo, Positiva entero Hexadecimal cadenas literales ("0xA" -> 10) fueron tratados como numérico.Yo necesitaba para ser numérico válido.

Luego he modificado la lógica de tener esto en cuenta.

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

Si usted está preocupado acerca de la creación de la regex cada vez que se llama a la función, a continuación, puede escribirlo en 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, ''));
  };
}());

Entonces tomé CMSs +30 casos de prueba y se clonó el las pruebas en jsfiddle añadido mi extra de casos de prueba y mi descrito anteriormente solución.

No puede reemplazar el ampliamente aceptado/utilizado respuesta, pero si esto es más de lo que esperan como resultados de su función isNumeric, a continuación, espero que esto le sea de alguna ayuda.

EDITAR: Como se ha señalado por Bergi, hay otros posibles objetos que puedan ser considerados numérico y sería mejor a la lista blanca de la lista negra.Con esto en mente, me gustaría añadir a los criterios.

Quiero que mi función isNumeric considerar sólo Números o Cadenas de caracteres

Con esto en mente, sería mejor utilizar

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

Prueba 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>

Sí, la incorporada en el isNaN(object) va a ser mucho más rápido que cualquier regex de análisis, porque es construido y recopilado, en lugar de interpretarse sobre la marcha.

Aunque los resultados son un poco 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

Uso de la función isNaN.Yo creo que si prueba para !isNaN(yourstringhere) funciona muy bien para cualquiera de estas situaciones.

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

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

Se puede hacer sin RegExp como

function IsNumeric(data){
    return parseFloat(data)==data;
}

Me doy cuenta de que la pregunta original no menciona jQuery, pero si usted hace uso de jQuery, se puede hacer:

$.isNumeric(val)

Simple.

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

Si no me equivoco, este debe coincidir con cualquier código JavaScript valor de número, con exclusión de las constantes (Infinity, NaN) y la señal de los operadores de +/- (porque en realidad no son parte de la serie como yo de que se trate, que son independientes de los operadores):

Necesitaba esto para un tokenizer, donde enviar el número de JavaScript para la evaluación no era una opción...Definitivamente no es la más corta posible regular la expresión, pero creo que las capturas de todos los más finos matices de JavaScript del número de sintaxis.

/^(?:(?:(?:[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 serían:

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

Números no válidos sería

 - 00e1
 - 01e1
 - 00.0
 - 00x0
 - .
 - .e0
return (input - 0) == input && input.length > 0;

no funciona para mí.Cuando me ponen en estado de alerta y probado, input.length fue undefined.Creo que no hay ninguna propiedad para comprobar entero de longitud.Así que lo que hice fue

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

Funcionó bien.

Para mí, esta es la mejor manera:

isNumber : function(v){
   return typeof v === 'number' && isFinite(v);
}

El único problema que tuve con @CMS respuesta es la exclusión de NaN y el Infinito, que son números útiles para muchas situaciones.Una forma de comprobar si NaN's es comprobar que los valores numéricos que no iguales a sí mismos, NaN != NaN!Así que en realidad hay 3 pruebas de que te gustaría tratar con ...

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á muy cerca de la otra elegante respuesta, pero maneja los hex y otras representaciones de cadena de números.

Un valor entero que 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 se comprueban!

Aquí está un poco lil versión mejorada (probablemente la manera más rápida de salir de allí) que puedo usar en lugar de exacta jQuery variante, la verdad, no sé por qué no usar este:

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

La desventaja de la versión de jQuery es que si se pasa una cadena con los principales números y letras siguientes como "123abc" el parseFloat | parseInt se va a extraer el valor numérico de la fracción y devolver 123, PERO, el segundo guardia isFinite se producirá de todos modos.Con la unario + operador de morir en el primer guardia desde + lanza NaN para tales híbridos :) Un poco de rendimiento, pero creo que un sólido semántica de ganancia.

Me gustaría añadir lo siguiente:

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

Positivo números hexadecimales a empezar con 0x y los negativos de los números hexadecimales a empezar con -0x.Positivo oct números comienzan con 0 y negativo oct números comienzan con -0.Este se lleva más de lo que ya ha sido mencionado en cuenta, pero que incluye hexadecimal y octal los números, negativo científica, el Infinito y ha eliminado decimal científica (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));
}

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
  • De un solo cero, o de uno o más dígitos que no empiezan con 0, o nada tanto tiempo como un período de la siguiente manera
  • Un período que es seguido por 1 o más números

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 que funcione en todas las situaciones, pero yo podría estar equivocado.

Esto debería funcionar.Algunas de las funciones que se proporcionan aquí están errados, también debe ser más rápido que cualquier otra función aquí.

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

Explicó:

Crear una copia de sí mismo, a continuación, convierte el número a flotar, a continuación, se compara a sí mismo con el número original, si es que sigue siendo un número, (si integer o float) , y coincide con el número original, lo que significa, que es de hecho un número.

Se trabaja con las cadenas de texto numéricas así como simples números.No funciona con números hexadecimales.

Advertencia:utilice a su propio riesgo, no hay garantías.

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

function is_numeric(n)
{
 return (n != '' && !isNaN(parseFloat(n)) && isFinite(n));
}

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 ser utilizado.

Esto es parte de la lengua desde 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

Yo estoy usando la solución más simple:

function isNumber(num) {
    return parseFloat(num).toString() == num
}

Me doy cuenta de que esto se ha contestado muchas veces, pero el siguiente es un digno candidato que puede ser útil en algunas situaciones.

cabe señalar que se supone que '.42' NO es un número, y '4.' NO es un número, así que esto debe ser tomado en cuenta.

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

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

El isDecimal pasa a 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 entero o tiene una "canónica" representación de cadena, y todos los no-representación canónica debe ser rechazado.Así que echamos a un número y la espalda, y ver si el resultado es la cadena original.

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

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

var obj = {};
obj['4'] = 'canonical 4';
obj['04'] = 'alias of 4';
obj[4];  // prints 'canonical 4' to the console.

knockoutJs Inbuild de la biblioteca de funciones de validación

Por ampliar el campo validado

1) número de

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

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ígitos

self.number = ko.observable(numberValue).extend({ dígito: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).extend({ min:5}).extend({ max:10});

Este campo acepta valor entre 5 y 10

TestCase

numberValue = '5'    --> true
numberValue = '6'    --> true
numberValue = '6.5'  --> true
numberValue = '9'    --> true
numberValue = '11'   --> false
numberValue = '0'    --> false
numberValue = ''    --> false

Usted puede minimizar esta función en un montón de camino, y también se puede implementar con una costumbre regex 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)
});
function inNumeric(n){
   return Number(n).toString() === n;
}

Si n es numérico Number(n) se devuelve el valor numérico y toString() hará retroceder a una cadena.Pero si n no es numérico Number(n) volverá NaN por lo que no coincide con el original n

Creo que parseFloat función puede hacer todo el trabajo.La función a continuación pasa todas las pruebas en esta página, incluyendo isNumeric(Infinity) == true:

function isNumeric(n) {

    return parseFloat(n) == n;
}

@CMS respuesta:El fragmento error en los espacios en blanco de los casos en mi máquina utilizando nodejs.Lo he combinado con @joel respuesta a la siguiente:

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

Yo unittested con los casos que se encuentran las carrozas:

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

y en aquellos casos que no son de su flota (incluyendo el vacío de espacios en blanco y los objetos / matrices):

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

Todo funciona como se espera aquí.Tal vez te sea de ayuda.

El código fuente completo de este se puede encontrar aquí.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top