Domanda

Qual è il modo più pulito ed efficace per convalidare i numeri decimali in JavaScript?

Punti bonus per:

  1. Chiarezza.La soluzione dovrebbe essere pulita e semplice.
  2. Multipiattaforma.

Casi test:

01. IsNumeric('-1')      => true
02. IsNumeric('-1.5')    => true
03. IsNumeric('0')       => true
04. IsNumeric('0.42')    => true
05. IsNumeric('.42')     => true
06. IsNumeric('99,999')  => false
07. IsNumeric('0x89f')   => false
08. IsNumeric('#abcdef') => false
09. IsNumeric('1.2.3')   => false
10. IsNumeric('')        => false
11. IsNumeric('blah')    => false
È stato utile?

Soluzione

@ Risposta di Joel è abbastanza vicino, ma fallirà nei seguenti casi:

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

Qualche tempo fa ho dovuto implementare un IsNumeric funzione, per scoprire se una variabile conteneva un valore numerico, indipendentemente dalla sua tipologia, potrebbe essere un String contenente un valore numerico (ho dovuto considerare anche la notazione esponenziale, ecc.), a Number oggetto, praticamente qualsiasi cosa potrebbe essere passata a quella funzione, non ho potuto fare alcuna ipotesi sul tipo, prendendomi cura della coercizione del tipo (ad es. +true == 1; Ma true non dovrebbe essere considerato come "numeric").

Penso che valga la pena condividere questa serie di +30 test unitari apportato a numerose implementazioni di funzioni e condivido anche quella che supera tutti i miei test:

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

PS isNaN & è finito hanno un comportamento confuso a causa della conversione forzata in numero.Nell'ES6, Numero.isNaN & Numero.èFinito risolverebbe questi problemi.Tienilo a mente quando li usi.


Aggiornamento : Ecco come lo fa jQuery ora (2.2-stabile):

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

Aggiornamento : Angolare 4.3:

export function isNumeric(value: any): boolean {
    return !isNaN(value - parseFloat(value));
}

Altri suggerimenti

Arrrgh!Non ascoltare le risposte sulle espressioni regolari.RegEx è disgustoso per questo e non sto parlando solo di prestazioni.È così facile commettere errori impercettibili che è impossibile individuare errori con l'espressione regolare.

Se non puoi usare isNaN(), questo dovrebbe funzionare molto meglio:

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

Ecco come funziona:

IL (input - 0) l'espressione forza JavaScript a eseguire la coercizione del tipo sul valore di input;deve prima essere interpretato come un numero per l'operazione di sottrazione.Se la conversione in numero fallisce, il risultato sarà l'espressione NaN.Questo numerico il risultato viene quindi confrontato con il valore originale passato.Poiché il lato sinistro ora è numerico, viene nuovamente utilizzata la coercizione del tipo.Ora che l'input da entrambe le parti è stato forzato allo stesso tipo dallo stesso valore originale, penseresti che dovrebbero essere sempre gli stessi (sempre vero).Tuttavia, c'è una regola speciale che dice NaN non è mai uguale a NaN, quindi un valore che non può essere convertito in numero (e solo i valori che non possono essere convertiti in numeri) risulterà falso.

Il controllo della lunghezza è per un caso speciale che coinvolge stringhe vuote.Tieni inoltre presente che non rientra nel test 0x89f, ma ciò è dovuto al fatto che in molti ambienti è un modo corretto per definire un numero letterale.Se vuoi catturare quello scenario specifico potresti aggiungere un controllo aggiuntivo.Ancora meglio, se questo è il motivo per cui non lo usi isNaN() quindi avvolgi semplicemente la tua funzione isNaN() che può anche eseguire il controllo aggiuntivo.

In sintesi, se vuoi sapere se un valore può essere convertito in un numero, prova a convertirlo in un numero.


Sono tornato indietro e ho fatto qualche ricerca per Perché una stringa di spazi bianchi non ha avuto l'output previsto e penso di averlo capito ora:viene forzata una stringa vuota 0 piuttosto che NaN.Il semplice taglio della corda prima del controllo della lunghezza gestirà questo caso.

Eseguendo gli unit test rispetto al nuovo codice, fallisce solo sui valori letterali infinito e booleano, e l'unica volta che dovrebbe essere un problema è se stai generando codice (in realtà, chi digiterebbe un valore letterale e controllerà se è numerico?Dovresti Sapere), e sarebbe un codice strano da generare.

Ma, ancora una volta, l'unico motivo per usarlo è se per qualche motivo devi evitare isNaN().

In questo modo sembra funzionare bene:

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

E per testarlo:

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

Ho preso in prestito quella regex da http://www.codetoad.com/javascript/isnumeric.asp.Spiegazione:

/^ 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!interfaccia utente usa questo:

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

Funziona anche con numeri di tipo 0x23.

La risposta accettata non ha superato il test n. 7 e immagino sia perché hai cambiato idea.Quindi questa è una risposta alla risposta accettata, con la quale ho avuto problemi.

Durante alcuni progetti ho avuto l'esigenza di validare alcuni dati ed essere il più certo possibile che si tratti di un valore numerico javascript utilizzabile in operazioni matematiche.

jQuery e alcune altre librerie JavaScript includono già tale funzione, solitamente chiamata isNumeric.C'è anche un post su StackOverflow questa è stata ampiamente accettata come risposta, la stessa routine generale utilizzata dalle biblioteche sopra menzionate.

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

Innanzitutto, il codice precedente restituirebbe true se l'argomento fosse un array di lunghezza 1 e quel singolo elemento fosse di un tipo considerato numerico dalla logica precedente.Secondo me, se è un array, non è numerico.

Per alleviare questo problema, ho aggiunto un controllo per scontare gli array dalla logica

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

Naturalmente, potresti anche usare Array.isArray, jquery $.isArray o prototipo Object.isArray invece di Object.prototype.toString.call(n) !== '[object Array]'

Il mio secondo problema era che le stringhe letterali intere esadecimali negative ("-0xA" -> -10) non venivano conteggiate come numeriche.Tuttavia, le stringhe letterali intere esadecimali positive ("0xA" -> 10) sono state trattate come numeriche.Avevo bisogno che entrambi fossero numerici validi.

Ho quindi modificato la logica per tenerne conto.

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

Se sei preoccupato per la creazione della regex ogni volta che viene chiamata la funzione, potresti riscriverla all'interno di una chiusura, qualcosa del genere

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

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

Poi ho preso i CMS +30 casi di test e clonato il test su jsfiddle ho aggiunto i miei casi di test aggiuntivi e la mia soluzione sopra descritta.

Potrebbe non sostituire la risposta ampiamente accettata/utilizzata, ma se questo è più di quello che ti aspetti come risultato dalla tua funzione isNumeric, si spera che questo possa essere di aiuto.

MODIFICARE: Come sottolineato da Bergi, ci sono altri possibili oggetti che potrebbero essere considerati numerici e sarebbe meglio inserirli nella whitelist piuttosto che nella blacklist.Tenendo presente questo, aggiungerei dei criteri.

Voglio che la mia funzione isNumeric consideri solo numeri o stringhe

Con questo in mente, sarebbe meglio usare

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

Testare le soluzioni

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ì, quello integrato isNaN(object) sarà molto più veloce di qualsiasi analisi regex, perché è integrato e compilato, anziché interpretato al volo.

Sebbene i risultati siano leggermente diversi da quelli che stai cercando (Provalo):

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

Utilizza la funzione isNaN.Credo che se fai il test per !isNaN(yourstringhere) funziona bene per ognuna di queste situazioni.

A partire da jQuery 1.7, puoi utilizzare 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

Tieni presente che, a differenza di quanto hai detto, 0x89f è un numero valido (esa)

Può essere fatto senza RegExp as

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

Mi rendo conto che la domanda originale non menzionava jQuery, ma se usi jQuery, puoi fare:

$.isNumeric(val)

Semplice.

https://api.jquery.com/jQuery.isNumeric/ (a partire da jQuery 1.7)

Se non sbaglio, dovrebbe corrispondere a qualsiasi valore numerico JavaScript valido, escluse le costanti (Infinity, NaN) e gli operatori di segno +/- (perché per quanto mi riguarda in realtà non fanno parte del numero, sono operatori separati):

Ne avevo bisogno per un tokenizzatore, dove inviare il numero a JavaScript per la valutazione non era un'opzione...Non è sicuramente l'espressione regolare più breve possibile, ma credo che catturi tutte le sottigliezze più fini della sintassi dei numeri di 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

I numeri validi includono:

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

I numeri non validi sarebbero

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

non ha funzionato per me.Quando ho inserito un avviso e ho testato, input.length era undefined.Penso che non ci sia alcuna proprietà per controllare la lunghezza intera.Quindi quello che ho fatto è stato

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

Ha funzionato bene.

Per me, questo è il modo migliore:

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

L'unico problema che ho avuto con @CMS risposta è l'esclusione di NaN e Infinito, che sono numeri utili per molte situazioni.Un modo per verificare NaNè controllare i valori numerici che non sono uguali a se stessi, NaN != NaN!Quindi ci sono davvero 3 prove che vorresti affrontare...

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

Il mio isComparableNumber è abbastanza vicino a un altro elegante risposta, ma gestisce rappresentazioni esadecimali e altre rappresentazioni di numeri in formato stringa.

Un valore intero può essere verificato da:

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

In questo modo è più semplice e veloce!Tutti i test sono controllati!

Ecco una versione leggermente migliorata (probabilmente la soluzione più veloce disponibile) che utilizzo al posto della variante esatta di jQuery, non so davvero perché non utilizzino questa:

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

Lo svantaggio della versione di jQuery è che se passi una stringa con numeri iniziali e lettere finali like "123abc" IL parseFloat | parseInt estrarrà la frazione numerica e restituirà 123, MA, la seconda guardia isFinite fallirà comunque.Con l'unario + Operatore morirà alla prima guardia poiché + lancia Nan per tali ibridi :) Un po 'di performance, ma penso un solido guadagno semantico.

Vorrei aggiungere quanto segue:

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

I numeri esadecimali positivi iniziano con 0x e i numeri esadecimali negativi iniziano con -0x.I numeri ott positivi iniziano con 0 e i numeri ott negativi iniziano con -0.Questo prende in considerazione la maggior parte di ciò che è già stato menzionato, ma include numeri esadecimali e ottali, scientifico negativo, Infinito e ha rimosso il scientifico decimale (4e3.2 non è valido).

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 paio di test da aggiungere:

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

Mi è venuta in mente questa:

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

La soluzione copre:

  • Un segno negativo opzionale all'inizio
  • Un singolo zero, o una o più cifre che non iniziano con 0, o nulla purché segua un punto
  • Un punto seguito da 1 o più numeri

La mia soluzione,

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

Sembra funzionare in ogni situazione, ma potrei sbagliarmi.

Questo dovrebbe funzionare.Alcune delle funzioni fornite qui sono difettose, inoltre dovrebbero essere più veloci di qualsiasi altra funzione qui.

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

Spiegato:

Crea una copia di se stesso, quindi converte il numero in float, quindi si confronta con il numero originale, se è ancora un numero, (intero o float), e corrisponde al numero originale, ciò significa che è effettivamente un numero.

Funziona con stringhe numeriche e numeri semplici.Non funziona con i numeri esadecimali.

Avvertimento:utilizzare a proprio rischio, nessuna garanzia.

Nessuna delle risposte ritorna false per le stringhe vuote, una soluzione per questo...

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

Per verificare se una variabile contiene un numero valido e non solo una stringa che sembra un numero,Number.isFinite(value) può essere utilizzata.

Questo fa parte della lingua da alloraES2015

Esempi:

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

Sto usando una soluzione più semplice:

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

Mi rendo conto che è stata data risposta molte volte, ma quanto segue è un candidato decente che può essere utile in alcuni scenari.

Va notato che si presume che ".42" non sia un numero, e '4.' non è un numero, quindi questo dovrebbe essere preso in considerazione.

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

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

IL isDecimal supera il seguente test:

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'idea qui è che ogni numero o intero ha una rappresentazione di stringa "canonica" e ogni rappresentazione non canonica dovrebbe essere rifiutata.Quindi eseguiamo il cast su un numero e viceversa, e vediamo se il risultato è la stringa originale.

L'utilità di queste funzioni dipende dal caso d'uso.Una caratteristica è questa stringhe distinte rappresentano numeri distinti (se entrambi superano il isNumber() test).

Questo è rilevante ad es.per i numeri come nomi di proprietà dell'oggetto.

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

knockoutJs Funzioni di convalida della libreria interna

Estendendolo il campo viene validato

1) numero

self.number = ko.observable(numberValue).extend({ numero:VERO});

Caso di prova

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) cifra

self.number = ko.observable(numberValue).extend({ cifra:VERO});

Caso di prova

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) minimo e massimo

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

Questo campo accetta solo valori compresi tra 5 e 10

Caso di prova

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

Puoi minimizzare questa funzione in molti modi e puoi anche implementarla con un'espressione regolare personalizzata per valori negativi o grafici personalizzati:

$('.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;
}

Se n è numerico Number(n) restituirà il valore numerico e toString() lo trasformerà nuovamente in una stringa.Ma se n non è numerico Number(n) sarà di ritorno NaN quindi non corrisponderà all'originale n

Penso che la funzione parseFloat possa fare tutto il lavoro qui.La funzione seguente supera tutti i test in questa pagina incluso isNumeric(Infinity) == true:

function isNumeric(n) {

    return parseFloat(n) == n;
}

La risposta di @CMS:Il tuo snippet non è riuscito sui casi di spazi bianchi sul mio computer utilizzando nodejs.Quindi l'ho combinato conLa risposta di @ Joel a quanto segue:

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

L'ho testato con quei casi che sono float:

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

e quei casi che non sono float (inclusi spazi bianchi vuoti e oggetti/array):

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

Qui funziona tutto come previsto.Forse questo aiuta.

È possibile trovare il codice sorgente completo per questo Qui.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top