Walidacja liczb dziesiętnych w JavaScript-IsNumeric()

Jaki jest najczystszy i najskuteczniejszy sposób walidacji liczb dziesiętnych w JavaScript?

Punkty Bonusowe za:

  1. jasność. Rozwiązanie powinno być czyste i proste.
  2. Cross-platform.

Przypadki testowe:

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

@odpowiedź Joela jest dość bliska, ale zawiedzie w następujących przypadkach:

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

Jakiś czas temu musiałem zaimplementować funkcję IsNumeric, aby dowiedzieć się, czy zmienna zawiera wartość liczbową, niezależnie od jej typu, może to być String zawierająca wartość liczbową (musiałem wziąć pod uwagę również notację wykładniczą itp.), obiekt Number, praktycznie wszystko można było przekazać do tej funkcji, nie mogłem dokonać żadnych założeń typu, dbając o przymus typu (np. +true == 1; ale true nie powinno być traktowane jako "numeric").

Myślę, że warto podzielić się tym zestawem +30 testy jednostkowe do wielu implementacji funkcji, a także współdzielenie tej, która przechodzi wszystkie moje testy: {]}

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

P. S. isNaN & isFinite mają mylące zachowanie z powodu wymuszonej konwersji na liczbę. W ES6, Liczba.isNaN & numer.isFinite naprawi te problemy. Pamiętaj o tym podczas korzystania z nich.


Update : oto jak jQuery robi to teraz (2.2-stable):

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

Update : kątowe 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/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-01 15:21:11

Arrrgh! Nie słuchaj odpowiedzi wyrażeń regularnych. RegEx jest do tego kiepski i nie mówię tylko o wydajności. Tak łatwo jest zrobić subtelne, niemożliwe do wykrycia błędy z wyrażeniem regularnym.

Jeśli nie możesz użyć isNaN(), powinno to działać znacznie lepiej:

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

Oto Jak to działa:

Wyrażenie (input - 0) zmusza JavaScript do wymuszenia typu na wartości wejściowej; musi być najpierw zinterpretowane jako Liczba dla operacji odejmowania. Jeśli ta konwersja na liczbę nie powiedzie się, wyrażenie spowoduje NaN. Wynik numeryczny jest następnie porównywany z oryginalną wartością, którą podałeś. Ponieważ lewa strona jest teraz numeryczna, ponownie używany jest typ przymusu. Teraz, gdy wejście z obu stron zostało wymuszone do tego samego typu z tej samej pierwotnej wartości, można by pomyśleć, że powinny być zawsze takie same (zawsze prawdziwe). Jednak istnieje specjalna zasada, która mówi, że NaN nigdy nie jest równa NaN, a więc wartość, której nie można przekształcić do liczby (i tylko wartości, które nie mogą być przekonwertowane na liczby) spowoduje false.

Sprawdzanie długości jest dla specjalnego przypadku z pustymi łańcuchami. Zauważ również, że spada na twój test 0x89f, ale dzieje się tak dlatego, że w wielu środowiskach jest to dobry sposób na zdefiniowanie liczby literalnie. Jeśli chcesz złapać ten konkretny scenariusz, możesz dodać dodatkową kontrolę. Nawet lepiej, jeśli to jest twój powód, dla którego nie używasz isNaN(), to po prostu owiń swoją własną funkcję wokół isNaN(), która może również wykonać dodatkową kontrolę.

W podsumowaniu, jeśli chcesz wiedzieć, czy wartość może być przekonwertowana na liczbę, spróbuj ją przekonwertować na liczbę.


Cofnąłem się i przeprowadziłem kilka badań dlaczego Biały ciąg znaków nie miał oczekiwanego wyniku i myślę, że teraz to Rozumiem: pusty ciąg jest wymuszany do 0, a nie do NaN. Wystarczy przycinanie Sznurka przed sprawdzeniem długości obsłuży ten przypadek.

Prowadzenie jednostki testy na nowy kod i to nie tylko na nieskończoność i boolean literałów, i jedyny czas, który powinien być problem jest, jeśli generujesz kod (naprawdę, kto by wpisać w literal i sprawdzić, czy jest numeryczny? Powinieneś znać ), a to byłby jakiś dziwny kod do wygenerowania.

Ale, znowu, jedynym powodem, aby tego użyć, jest to, że z jakiegoś powodu musisz unikać 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/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-28 20:47:01

Ten sposób wydaje się działać dobrze:

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

I przetestować:

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

Pożyczyłem ten regex od http://www.codetoad.com/javascript/isnumeric.asp . Wyjaśnienie:

/^ 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/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-20 14:22:56

Yahoo! UI używa tego:

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/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-02 00:39:05
function IsNumeric(num) {
     return (num >=0 || num < 0);
}

Działa to również dla liczb typu 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/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-16 13:01:37

Zaakceptowana odpowiedź oblała twój test # 7 i chyba dlatego, że zmieniłeś zdanie. Jest to więc odpowiedź na przyjętą odpowiedź, z którą miałem problemy.

Podczas niektórych projektów musiałem zweryfikować niektóre dane i być tak pewnym, jak to możliwe, że jest to wartość liczbowa javascript, która może być używana w operacjach matematycznych.

JQuery i niektóre inne biblioteki javascript już zawierają taką funkcję, Zwykle o nazwie isNumeric. Jest też post na stackoverflow , który został powszechnie przyjęty jako odpowiedź, ta sama ogólna procedura, której używają wyżej wymienione biblioteki.

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

Po pierwsze, powyższy kod zwróci true, jeśli argument będzie tablicą o długości 1, A pojedynczy element będzie typu uznanego za liczbowy przez powyższą logikę. Moim zdaniem, jeśli jest to tablica, to nie jest numeryczna.

Aby złagodzić ten problem, dodałem czek do tablic dyskontowych z logiki

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

Oczywiście, można użyj również Array.isArray, jquery $.isArray lub prototype Object.isArray zamiast Object.prototype.toString.call(n) !== '[object Array]'

Mój drugi problem polegał na tym, że ujemne szesnastkowe liczby całkowite ("-0XA" -> -10) nie były liczone jako liczbowe. Jednak dodatnie, szesnastkowe ciągi znaków ("0XA" - > 10) były traktowane jako liczbowe. Potrzebowałem, żeby obie były poprawne numerycznie.

Następnie zmodyfikowałem logikę, aby wziąć to pod uwagę.

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

Jeśli martwisz się o utworzenie wyrażenia regularnego za każdym razem, gdy funkcja jest wywoływana następnie możesz go przepisać w ramach zamknięcia, coś takiego jak to

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

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

Następnie wziąłem CMSs +30 przypadków testowych i sklonowałem testy na jsfiddle dodałem moje dodatkowe przypadki testowe i moje opisane powyżej rozwiązanie.

Może nie zastąpić powszechnie akceptowanej/używanej odpowiedzi, ale jeśli jest to więcej tego, czego oczekujesz jako wyników swojej funkcji isNumeric, mam nadzieję, że będzie to pomocne.

EDIT: jak wskazał Bergi , istnieją inne możliwe obiekty, które można uznać za numeryczne i lepiej byłoby białej listy niż czarnej listy. Mając to na uwadze, dodałbym do kryteriów.

Chcę, aby moja funkcja isNumeric uwzględniała tylko liczby lub ciągi

Mając to na uwadze, lepiej byłoby użyć

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

Badanie roztworów

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/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-05 12:56:31

Tak, wbudowany isNaN(object) będzie znacznie szybsze niż jakiekolwiek parsowanie regex, ponieważ jest wbudowane i skompilowane, zamiast interpretowane w locie.

Chociaż wyniki są nieco inne niż to, czego szukasz ( spróbuj):

                                              // 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/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-08 14:39:20

Od jQuery 1.7 można używać 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

Zauważ, że w przeciwieństwie do tego, co powiedziałeś, 0x89f jest poprawną liczbą (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/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-18 09:01:43

Użyj funkcji isNaN. Wierzę, że jeśli testujesz na !isNaN(yourstringhere) to działa dobrze w każdej z tych sytuacji.

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-10 16:19:51

Można to zrobić bez wyrażenia regularnego jako

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/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-22 15:08:05

Zdaję sobie sprawę, że oryginalne pytanie nie wspominało o jQuery, ale jeśli używasz jQuery, możesz to zrobić:

$.isNumeric(val)

Proste.

Https://api.jquery.com/jQuery.isNumeric/ (od 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/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-13 16:42:50

Jeśli się nie mylę, to powinno pasować do każdej poprawnej wartości liczby JavaScript, z wyłączeniem stałych (Infinity, NaN) oraz operatory znaków+/- (ponieważ nie są one rzeczywiście częścią liczby, o ile mi wiadomo, są oddzielnymi operatorami):

Potrzebowałem tego dla tokenizera, gdzie wysyłanie numeru do JavaScript do oceny nie było opcją... Zdecydowanie nie jest to najkrótsze możliwe Wyrażenie regularne, ale wierzę, że łapie wszystkie subtelności JavaScript składnia liczb.

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

Poprawne liczby to:

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

Nieprawidłowe liczby to

 - 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/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-10 16:14:12
return (input - 0) == input && input.length > 0;
Nie zadziałało na mnie. Kiedy wprowadziłem alarm i przetestowałem, input.length było undefined. Myślę, że nie ma właściwości do sprawdzania długości całkowitej. Więc to co zrobiłem było
var temp = '' + input;
return (input - 0) == input && temp.length > 0;
Zadziałało dobrze.
 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/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-05 13:04:36

Dla mnie to najlepszy sposób:

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/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-28 11:30:26

Wartość całkowitą można zweryfikować przez:

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

Ten sposób jest łatwiejszy i szybszy! Wszystkie testy są sprawdzone!

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-06 18:36:05

Oto lil bit improved version (chyba najszybszy sposób), którego używam zamiast dokładnego wariantu jQuery, naprawdę Nie wiem dlaczego nie używają tego:

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

Minusem wersji jQuery jest to, że jeśli przekażesz ciąg znaków z wiodącymi cyframi i końcowymi literami, takimi jak "123abc" parseFloat | parseInt wyodrębni ułamek liczbowy i zwróci 123, ale drugi strażnik isFinite i tak go zawiedzie. Z operatorem uniary + umrze na pierwszym strażniku od + rzuca NaN na takie hybrydy :) Trochę wydajności, ale myślę, że solidny zysk semantyczny.

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-20 16:48:18

Jedyny problem jaki miałem z odpowiedzią @CMS jest wykluczenie NaN i nieskończoności, które są przydatnymi liczbami w wielu sytuacjach. Jednym ze sposobów sprawdzania NaN jest sprawdzanie wartości liczbowych, które nie są sobie równe, NaN != NaN! Więc są naprawdę 3 testy, z którymi chciałbyś się uporać ...

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

Mój isComparableNumber jest dość blisko innej eleganckiej odpowiedzi, ale obsługuje hex i inne reprezentacje ciągów liczb.

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-05 13:03:22

Kilka testów do dodania:

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

Wymyśliłem to:

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

Rozwiązanie obejmuje:

  • opcjonalny znak ujemny na początku
  • pojedyncze zero, lub jedna lub więcej cyfr nie zaczynających się od 0, lub nic, tak długo, jak następuje kropka
  • okres, po którym następuje 1 lub więcej liczb
 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/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-25 09:25:24

Moje rozwiązanie,

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;
}
Wygląda na to, że działa w każdej sytuacji, ale mogę się mylić.
 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/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-25 09:35:22

To powinno zadziałać. Niektóre z podanych tutaj funkcji są wadliwe, również powinny być szybsze niż jakakolwiek inna funkcja tutaj.

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

Wyjaśnione:

Tworzy swoją kopię, następnie zamienia liczbę na zmiennoprzecinkową, a następnie porównuje ją z liczbą pierwotną, jeśli nadal jest liczbą (czy to całkowitą czy zmiennoprzecinkową) i pasuje do liczby pierwotnej, to znaczy , że rzeczywiście jest liczbą.

Działa zarówno z ciągami liczbowymi, jak i zwykłymi liczbami. Nie działa w systemie szesnastkowym liczby.

Ostrzeżenie: używaj na własne ryzyko, bez gwarancji.

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-07 21:59:27

Chciałbym dodać:

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

Dodatnie liczby sześciokątne rozpoczynają się od 0x, a ujemne od -0x. Dodatnie liczby OKT rozpoczynają się od 0, A ujemne liczby OKT rozpoczynają się od -0. Ten bierze pod uwagę większość tego, co już zostało wymienione, ale obejmuje liczby szesnastkowe i ósemkowe, ujemne naukowe, Nieskończoność i usunięto dziesiętne naukowe (4e3.2 nie jest poprawne).

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/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-05 13:02:03

Używam prostszego rozwiązania:

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/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-16 12:25:25

Żadna z odpowiedzi nie zwraca false dla pustych łańcuchów...

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/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-10 16:13:18

@odpowiedź CMS: Twój urywek nie powiódł się w przypadku białych znaków na moim komputerze przy użyciu nodejs. Więc połączyłem go z @Joel ' s answer to the following:

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

Połączyłem to z tymi przypadkami, które są pływakami:

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

I te przypadki, które nie są pływakami (w tym pustymi białymi spacjami i obiektami / tablicami):

    var t = [
        'hallo',
        [],
        {},
        'jklsd0',
        '',
        "\t",
        "\n",
        ' '
    ];
Tutaj wszystko działa zgodnie z oczekiwaniami. Może to pomoże.

Pełny kod źródłowy można znaleźć tutaj .

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:53

Następujące wydaje się działać dobrze w wielu przypadkach:

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

Jest to zbudowane na podstawie tej odpowiedzi (która jest również dla tej odpowiedzi): 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/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:30

Zdaję sobie sprawę, że odpowiedź była wielokrotnie, ale poniżej jest przyzwoity kandydat, który może być przydatny w niektórych scenariuszach.

Należy zauważyć, że zakłada ona, że".42 'nie jest liczbą, a" 4."nie jest liczbą, więc należy to wziąć pod uwagę.

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

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

isDecimal przechodzi następujący 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');
}

Chodzi o to, że każda liczba lub liczba całkowita ma jedną "kanoniczną" reprezentację łańcuchową, a każda reprezentacja niekanoniczna powinna zostać odrzucona. Więc my rzut do liczby i z powrotem, i sprawdzić, czy wynik jest oryginalny ciąg.

To, czy te funkcje są dla Ciebie przydatne, zależy od przypadku użycia. Jedną z cech jest to, że różne ciągi reprezentują różne liczby (jeśli oba przechodzą test isNumber()).

Jest to istotne np. dla liczb jako nazw właściwości obiektów.

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/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-15 00:17:22

KnockoutJs inbuild library validation functions

Poprzez rozszerzenie pola get validated

1) Liczba

self.number = ko.observable(numberValue).extend ({ numer: 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) cyfra

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

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

To pole akceptuje tylko wartość między 5 a 10

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/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-10 16:17:14

Aby sprawdzić, czy zmienna zawiera poprawną liczbę, a nie tylko ciąg, który wygląda jak liczba, Number.isFinite(value) może być używany.

Jest to część języka, ponieważ ES2015

Przykłady:

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/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-12 20:00:46

Możesz zminimalizować tę funkcję na wiele sposobów, a także zaimplementować ją za pomocą niestandardowego wyrażenia regularnego dla wartości ujemnych lub niestandardowych Wykresów:

$('.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/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-23 15:16:43
function inNumeric(n){
   return Number(n).toString() === n;
}

Jeśli n jest liczbowe Number(n) zwróci wartość liczbową i toString() zwróci ją z powrotem do ciągu znaków. Ale jeśli n nie jest numeryczne Number(n) zwróci NaN więc nie będzie pasować do oryginału 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/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-18 21:28:25