48 Pertanyaan: Validasi angka desimal dalam JavaScript - IsNumeric ()

pertanyaan dibuat di Wed, Dec 7, 2016 12:00 AM

Apa cara terbersih dan paling efektif untuk memvalidasi angka desimal dalam JavaScript?

Poin bonus untuk:

  1. Kejelasan. Solusi harus bersih dan sederhana.
  2. Cross-platform.

Uji kasus:

 
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
    
2269
  1. Hanya catatan 99.999 adalah angka yang valid di Prancis, sama dengan 99.999 dalam format uk /us, jadi jika Anda membaca dalam string dari mengucapkan formulir input maka 99.999 mungkin benar.
    2008-08-20 14: 31: 46Z
  2. 2009-11-23 18: 05: 06Z
  3. Koma desimal adalah standar di seluruh Eropa dan Rusia (kecuali Inggris)
    2011-02-16 14: 29: 25Z
  4. jQuery 1.7 telah memperkenalkan fungsi utilitas jQuery.isNumeric: api.jquery.com/jQuery.isNumeric
    2011-11-16 20: 04: 53Z
  5. jQuery.isNumeric akan gagal dalam test case ketujuh OP (IsNumeric('0x89f') => *false*). Namun, saya tidak yakin apakah saya setuju dengan test case ini.
    2012-08-27 16: 42: 48Z
30 Jawaban                              30                         

@ jawaban Joel cukup dekat, tetapi akan gagal dalam kasus berikut:

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

Beberapa waktu lalu saya harus mengimplementasikan fungsi IsNumeric, untuk mengetahui apakah variabel berisi nilai numerik, terlepas dari jenisnya , itu bisa berupa String yang berisi nilai numerik (saya harus pertimbangkan juga notasi eksponensial, dll.), objek Number, hampir semua hal dapat diteruskan ke fungsi itu, saya tidak bisa membuat asumsi tipe apa pun, mengurus tipe paksaan (mis. +true == 1; tapi true tidak boleh dianggap sebagai "numeric") .

Saya pikir layak membagikan set ini +30 unit test dibuat untuk banyak implementasi fungsi, dan juga bagikan yang melewati semua pengujian saya:

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

PS isNaN & isFinite memiliki perilaku yang membingungkan karena konversi paksa. ke nomor. Di ES6, Number.isNaN &amp ; Number.isFinite akan memperbaiki masalah ini . Ingatlah hal itu saat menggunakannya.


Pembaruan : Begini caranya jQuery melakukannya sekarang (2.2-stable) :

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

Pembaruan : Angular 4.3 ::

 
export function isNumeric(value: any): boolean {
    return !isNaN(value - parseFloat(value));
}
    
2836
2018-06-01 15: 21: 11Z
  1. ini gagal dengan lokal lain tempat kami menggunakan koma desimal, tetapi tambahkan `n = n.replace (/, /,". "); ' sebelum kembali untuk memperbaikinya.
    2011-04-26 02: 14: 28Z
  2. @ RobG, perilaku itu disengaja, 2e308 > Number.MAX_VALUE sejak 2e308 == Infinity. Jika Anda menginginkan fungsi yang mengembalikan true juga untuk nilai tak terhingga positif dan negatif, periksa fungsi Tidak. 2 di test suite . Ceria.
    2011-06-24 18: 30: 34Z
  3. Ngomong-ngomong, tes unit sekarang digunakan oleh proyek jQuery
    2012-01-31 19: 13: 56Z
  4. 2012-12-01 11: 33: 20Z
  5. Solusi di sini adalah dengan menggunakan JQuery. Mereka memiliki implementasi yang lebih baik dari ini sekarang: github.com/jquery /jquery /blob /master /src /core.js # L230
    2013-10-06 04: 44: 48Z

Arrrgh! Jangan dengarkan jawaban ekspresi reguler. RegEx jijik untuk ini, dan saya tidak hanya berbicara kinerja. Sangat mudah untuk membuat kesalahan yang tidak kentara, tidak mungkin terjadi dengan ekspresi reguler Anda.

Jika Anda tidak dapat menggunakan isNaN(), ini seharusnya bekerja lebih baik:

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

Ini cara kerjanya:

Ekspresi (input - 0) memaksa JavaScript untuk melakukan ketik paksaan pada nilai input Anda; pertama-tama harus ditafsirkan sebagai angka untuk operasi pengurangan. Jika konversi ke nomor gagal, ekspresi akan menghasilkan NaN. Hasil numerik ini kemudian dibandingkan dengan nilai asli yang Anda berikan. Karena sisi kiri sekarang adalah numerik, jenis pemaksaan digunakan lagi. Sekarang input dari kedua belah pihak dipaksa untuk jenis yang sama dari nilai asli yang sama, Anda akan berpikir mereka harus selalu sama (selalu benar). Namun, ada aturan khusus yang mengatakan NaN tidak pernah sama dengan NaN, sehingga nilai yang tidak dapat dikonversi ke angka (dan hanya nilai yang tidak dapat dikonversi ke angka) akan menghasilkan false.

Pemeriksaan panjangnya untuk kasus khusus yang melibatkan string kosong. Perhatikan juga bahwa itu jatuh pada tes 0x89f Anda, tetapi itu karena di banyak lingkungan itu cara yang baik untuk mendefinisikan angka literal. Jika Anda ingin menangkap skenario spesifik itu, Anda bisa menambahkan cek tambahan. Bahkan lebih baik, jika itu alasan Anda untuk tidak menggunakan isNaN() maka cukup bungkus fungsi Anda sendiri di sekitar isNaN() yang juga dapat melakukan pemeriksaan tambahan.

Singkatnya, jika Anda ingin tahu apakah suatu nilai dapat dikonversi ke angka, sebenarnya cobalah mengonversinya menjadi angka.


Saya kembali dan melakukan riset untuk mengapa string spasi putih tidak memiliki output yang diharapkan, dan saya pikir saya mengerti sekarang: string kosong dipaksakan ke 0 daripada NaN. Cukup dengan memangkas string sebelum pemeriksaan panjang akan menangani kasus ini.

Menjalankan pengujian unit terhadap kode baru dan hanya gagal pada infinity dan boolean literal, dan satu-satunya waktu yang seharusnya menjadi masalah adalah jika Anda membuat kode (sungguh, siapa yang akan mengetikkan literal dan memeriksa apakah ini numerik? Anda harus tahu ), dan itu akan menghasilkan kode aneh.

Tapi, sekali lagi, satu-satunya alasan untuk menggunakan ini adalah jika karena alasan tertentu Anda harus menghindari isNaN ().

    
325
2015-01-28 20: 47: 01Z
  1. bahkan lebih baik jika Anda hanya perlu menjelaskan kasus khusus 0x89f jika membungkus fungsi IsNumeric () di sekitar isNaN () yang kemudian membuat pemeriksaan khusus hanya jika isNaN () mengembalikan false.
    2008-11-25 18: 21: 54Z
  2. Ini gagal pada string spasi putih, mis. IsNumeric(' '), IsNumeric('\n\t'), dll semua mengembalikan true
    2009-12-02 04: 36: 06Z
  3. Itu juga akan gagal pada Number liter IsNumeric(5) == false; periksa set unit test yang saya posting, fungsi ini adalah angka 16 pada test suite. stackoverflow.com/questions/18082/…
    2009-12-02 05: 52: 38Z
  4. Saya tidak percaya tidak ada yang menunjukkan penggunaan ekspresi reguler (ganti) setelah peringatan tentang tidak menggunakan ekspresi reguler ... Memang, penggantian spasi putih lebih sederhana daripada angka parse, tetapi masih pasti "icky".
    2013-06-20 14: 41: 58Z
  5. @ Oriol Itu masalah besar ... tanpa perbaikan keamanan yang dirilis setelah tanggal itu, menjauh dari XP harus menjadi prioritas.
    2013-10-20 04: 38: 12Z

Cara ini sepertinya berfungsi dengan baik:

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

Dan untuk mengujinya:

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

Saya meminjam regex itu dari http://www.codetoad.com/javascript/isnumeric.asp . Penjelasan:

 
/^ 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
    
61
2008-08-20 14: 22: 56Z
  1. //JUGA HARUS DITAMBAHKAN KE HASIL UJI ANDA + = (! IsNumeric ('-')? "Lulus": "Fail") + ": IsNumeric (' - ') = > false \n "; hasil + = (! IsNumeric ('01 ')? "Lulus": "Gagal") + ": IsNumeric ('01') = > false \n"; hasil + = (! IsNumeric ('- 01')? "Lulus": "Gagal") + ": IsNumeric ('- 01') = > false \n"; hasil + = (! IsNumeric ('000')? "Lulus": "Gagal") + ": IsNumeric ('000') = > false \n";
    2010-01-28 01: 47: 01Z
  2. apa fungsinya? /^ - {0,1} \d * \. {0,1} \d + $/
    2016-09-02 23: 42: 43Z
  3. dapat "{0,1}" diganti dengan "?", sehingga regexp Anda akan terlihat seperti ini: /^-?\d*\.?\d+ $/?
    2016-10-14 10: 20: 13Z

Yahoo! UI menggunakan ini:

 
isNumber: function(o) {
    return typeof o === 'number' && isFinite(o);
}
    
48
2013-04-02 00: 39: 05Z
  1. Itu lebih memeriksa tipe variabel yang bertentangan dengan konten nomor. Ini juga akan gagal pada angka yang dibuat dengan new Number(1).
    2011-06-23 05: 33: 17Z
  2. Seperti yang dikatakan alex, ini sebenarnya tidak menjawab pertanyaan yang diajukan karena ini akan gagal jika o = "1001".
    2013-01-25 23: 49: 26Z
 
function IsNumeric(num) {
     return (num >=0 || num < 0);
}

Ini juga berfungsi untuk nomor tipe 0x23.

    
46
2012-06-16 13: 01: 37Z
  1. IsNumeric(''), IsNumeric(' '), IsNumeric(true), IsNumeric(false), IsNumeric(null) mengembalikan true alih-alih false.
    2013-09-07 16: 29: 15Z
  2. 2014-04-02 16: 27: 27Z

Jawaban yang diterima gagal dalam tes Anda # 7 dan saya rasa itu karena Anda berubah pikiran. Jadi ini adalah respons terhadap jawaban yang diterima, yang dengannya saya memiliki masalah.

Selama beberapa proyek, saya harus memvalidasi beberapa data dan memastikan bahwa itu adalah nilai numerik javascript yang dapat digunakan dalam operasi matematika.

jQuery, dan beberapa perpustakaan javascript lainnya sudah menyertakan fungsi seperti itu, biasanya disebut isNumeric. Ada juga pos di stackoverflow yang telah diterima secara luas sebagai jawabannya, rutinitas umum yang sama seperti perpustakaan yang disebutkan sebelumnya adalah menggunakan.

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

Pertama, kode di atas akan mengembalikan true jika argumennya adalah array dengan panjang 1, dan elemen tunggal itu merupakan tipe yang dianggap numerik oleh logika di atas. Menurut pendapat saya, jika ini array maka bukan numerik.

Untuk mengatasi masalah ini, saya menambahkan tanda centang pada diskon array dari logika

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

Tentu saja, Anda juga bisa menggunakan Array.isArray, jquery $.isArray atau prototipe Object.isArray alih-alih Object.prototype.toString.call(n) !== '[object Array]'

Masalah kedua saya adalah bahwa string literal heksadesimal Negatif Heksadesimal ("-0xA" - > -10) tidak dihitung sebagai numerik. Namun, string literal heksadesimal Positif Heksadesimal ("0xA" - > 10) diperlakukan sebagai numerik. Saya perlu keduanya menjadi angka yang valid.

Saya kemudian memodifikasi logika untuk memperhitungkan ini.

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

Jika Anda khawatir tentang pembuatan regex setiap kali fungsi dipanggil maka Anda bisa menulis ulang dalam penutupan, sesuatu seperti ini

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

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

Saya kemudian mengambil CMS +30 test case dan kloning pengujian pada jsfiddle menambahkan kotak uji tambahan dan solusi yang saya jelaskan di atas.

Ini mungkin tidak menggantikan jawaban yang diterima /digunakan secara luas tetapi jika ini lebih dari apa yang Anda harapkan sebagai hasil dari fungsi isNumerik Anda, semoga ini akan membantu.

EDIT: Seperti yang ditunjukkan oleh Bergi , ada objek lain yang mungkin bisa dianggap numerik dan akan lebih baik untuk daftar putih daripada daftar hitam. Dengan mengingat hal ini, saya akan menambah kriteria.

Saya ingin fungsi isNumeric saya hanya mempertimbangkan Angka atau String

Dengan mengingat hal ini, akan lebih baik menggunakan

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

Uji solusinya

 
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>
    
43
2018-01-05 12: 56: 31Z
  1. Ini menurut saya fungsi yang paling terlindung; yang terakhir. Jawaban yang diterima mungkin mencakup 99,99% dari semua kasus tetapi yang ini mungkin 100% dari a) kasus dengan overhead kecil.
    2014-01-07 03: 59: 31Z
  2. Anda lupa tentang "99.999" Foating-Point literal. Ini adalah angka yang valid di semua Eropa kecuali UK
    2016-01-28 14: 59: 08Z
  3. Itu tidak dilupakan, itu bukan sesuatu yang saya anggap numerik dalam arti angka Javascript, OP juga menyatakan IsNumeric('99,999') => false
    2016-01-28 18: 50: 47Z

Ya, isNaN(object) bawaan akan jauh lebih cepat daripada sembarang regex parsing, karena built-in dan dikompilasi, alih-alih ditafsirkan dengan cepat.

Meskipun hasilnya agak berbeda dengan yang Anda cari ( coba saja ):

 
                                              // 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
    
33
2013-08-08 14: 39: 20Z

Gunakan fungsi isNaN. Saya percaya jika Anda menguji !isNaN(yourstringhere) itu berfungsi dengan baik untuk semua situasi ini.

    
16
2016-02-10 16: 19: 51Z
  1. Catatan:! isNaN (null) == true karena Number (null) == 0
    2008-10-15 04: 50: 47Z
  2. if (! (x == null || isNaN (x))) lansiran ("isNumeric"); //Tapi solusi ini menerima 0x40 sehingga masih bukan yang diinginkan oleh op.
    2008-12-15 04: 58: 18Z
  3. Perhatikan bahwa isNaN ("Infinity") === false, yang mungkin juga bukan yang Anda inginkan (tetapi juga tidak akan terjadi dalam kehidupan nyata).
    2010-02-10 15: 13: 50Z

Sejak jQuery 1.7, Anda dapat menggunakan 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

Perhatikan bahwa tidak seperti apa yang Anda katakan, 0x89f adalah angka yang valid (hexa)

    
15
2013-02-18 09: 01: 43Z
  1. OP ingin angka desimal yang valid, jadi jQuery isNumeric tidak cocok. Itu juga gagal untuk angka yang sangat besar.
    2015-11-02 21: 21: 50Z

Itu bisa dilakukan tanpa RegExp sebagai

 
function IsNumeric(data){
    return parseFloat(data)==data;
}
    
11
2008-08-22 15: 08: 05Z
  1. tidak seharusnya ===
    2009-11-23 18: 04: 06Z
  2. Jika kita menggunakan ==, itu akan mengembalikan true bahkan untuk angka-angka yang disajikan sebagai string. Jadi "42" akan dihitung sebagai angka yang valid jika "==" dan akan dihitung sebagai tidak valid dalam kasus ===
    2009-11-25 18: 38: 44Z
  3. ini mengembalikan true pada "-0.", "-.0", ".0" dan "0."
    2012-09-28 22: 16: 44Z

Saya menyadari pertanyaan asli tidak menyebutkan jQuery, tetapi jika Anda menggunakan jQuery, Anda dapat melakukannya:

 
$.isNumeric(val)

Sederhana.

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

    
7
2014-01-13 16: 42: 50Z

Jika saya tidak salah, ini harus cocok dengan nilai angka JavaScript yang valid, tidak termasuk konstanta (Infinity, NaN) dan operator tanda +/- (karena mereka sebenarnya bukan bagian dari nomor sejauh yang saya ketahui, adalah operator terpisah):

Saya membutuhkan ini untuk tokenizer, di mana mengirim nomor ke JavaScript untuk evaluasi bukan pilihan ... Ini jelas bukan ekspresi reguler sesingkat mungkin, tapi saya percaya itu menangkap semua seluk-beluk halus sintaksis angka JavaScript yang lebih baik.  

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

Angka yang valid akan mencakup:

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

Angka yang tidak valid adalah

 
 - 00e1
 - 01e1
 - 00.0
 - 00x0
 - .
 - .e0
    
6
2016-02-10 16: 14: 12Z
 
return (input - 0) == input && input.length > 0;

tidak bekerja untuk saya. Ketika saya mengaktifkan dan menguji, input.length adalah undefined. Saya pikir tidak ada properti untuk memeriksa panjang bilangan bulat. Jadi yang saya lakukan adalah

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

Berhasil.

    
6
2018-01-05 13: 04: 36Z

Bagi saya, ini adalah cara terbaik:

 
isNumber : function(v){
   return typeof v === 'number' && isFinite(v);
}
    
5
2010-05-28 11: 30: 26Z
  1. Sayangnya, ini adalah pemeriksa angka STRICT yang akan gagal untuk semua string yang berisi huruf numerik saja, seperti "0" dll ...
    2013-05-20 16: 36: 43Z

Satu-satunya masalah yang saya miliki dengan jawaban @ CMS adalah pengecualian NaN dan Infinity, yang merupakan angka berguna untuk banyak situasi . Salah satu cara untuk memeriksa NaN adalah dengan memeriksa nilai numerik yang tidak sama dengan diri mereka, NaN != NaN! Jadi sebenarnya ada 3 tes yang ingin Anda tangani ...

 
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

IsComparableNumber saya cukup dekat dengan jawaban yang elegan, tetapi menangani representasi angka hex dan string lainnya.

    
5
2018-01-05 13: 03: 22Z

Nilai integer dapat diverifikasi oleh:

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

Cara ini lebih mudah dan lebih cepat! Semua tes diperiksa!

    
4
2013-01-06 18: 36: 05Z

Inilah versi yang ditingkatkan sedikit lil (mungkin cara tercepat di luar sana) yang saya gunakan daripada varian jQuery yang tepat, saya benar-benar tidak tahu mengapa mereka tidak menggunakan yang ini:

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

Kelemahan dari versi jQuery adalah bahwa jika Anda meneruskan string dengan angka dan huruf trailing terkemuka seperti "123abc", parseFloat | parseInt akan mengekstraksi pecahan angka dan mengembalikan 123, TETAPI, penjaga kedua isFinite akan tetap gagal. Dengan operator + unary itu akan mati di penjaga pertama sejak + melempar NaN untuk hibrida tersebut :) Sedikit kinerja namun menurut saya keuntungan semantik yang solid.

    
4
2013-05-20 16: 48: 18Z
  1. Waspadai unary '+' akan memanggil valueOf () pada objek - lihat ini jsfiddle . Selain itu, ini juga gagal untuk memimpin spasi putih, seperti halnya jawaban utama.
    2013-09-24 23: 34: 21Z

Saya ingin menambahkan yang berikut:

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

Angka heks positif dimulai dengan 0x dan angka heks negatif dimulai dengan -0x. Angka oktaf positif dimulai dengan 0 dan angka oktaf negatif dimulai dengan -0. Yang ini mengambil sebagian besar dari apa yang telah disebutkan, tetapi termasuk angka heks dan oktal, ilmiah negatif, Infinity dan telah menghapus ilmiah desimal (4e3.2 tidak valid).

 
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));
}
    
4
2018-01-05 13: 02: 03Z
  1. Apakah itu berfungsi dengan string kosong?
    2014-07-25 14: 19: 08Z

Beberapa tes untuk ditambahkan:

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

Saya datang dengan ini:

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

Solusinya meliputi:

  • Tanda negatif opsional di awal
  • Satu nol, atau satu digit atau lebih yang tidak dimulai dengan 0, atau tidak ada selama periode mengikuti
  • Periode yang diikuti oleh 1 angka atau lebih
3
2011-05-25 09: 25: 24Z

Solusi saya,

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

Tampaknya berfungsi dalam setiap situasi, tapi saya mungkin salah.

    
3
2011-05-25 09: 35: 22Z
  1. Regex itu akan kurang membingungkan jika Anda tidak perlu melarikan diri karakter, gunakan ? untuk {0,1} dan \d untuk [0-9]. Juga + dan kemudian balut dengan (?:){0,1}, Anda juga dapat menggunakan * dan lupakan kelompok (bukan) yang menangkap.
    2013-08-07 22: 04: 07Z

Ini seharusnya berhasil. Beberapa fungsi yang disediakan di sini cacat, juga harus lebih cepat daripada fungsi lain di sini.

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

Dijelaskan:

Buat salinannya sendiri, lalu ubah angka menjadi float, lalu bandingkan dengan nomor aslinya, jika masih berupa angka, (apakah bilangan bulat atau float), dan cocok dengan angka aslinya, itu berarti, memang sebuah angka.

Ini berfungsi dengan string numerik dan juga angka biasa. Tidak berfungsi dengan angka heksadesimal.

Peringatan: gunakan dengan risiko Anda sendiri, tanpa jaminan.

    
3
2013-08-07 21: 59: 27Z
  1. gunakan dengan risiko Anda sendiri, tidak ada jaminan Saya tidak akan menggunakan kode yang penulis tidak percayai;)
    2013-08-07 22: 00: 00Z
  2. @ Alex, Setidaknya punya pendapat sendiri tentang banyak hal. Jangan hanya mengkritik sepanjang waktu.
    2014-01-28 08: 35: 19Z

Tidak ada jawaban yang mengembalikan false untuk string kosong, perbaikan untuk itu ...

 
function is_numeric(n)
{
 return (n != '' && !isNaN(parseFloat(n)) && isFinite(n));
}
    
3
2016-02-10 16: 13: 18Z

Untuk memeriksa apakah suatu variabel berisi angka yang valid dan tidak hanya sebuah String yang terlihat seperti angka,  Number.isFinite(value) dapat digunakan.

Ini adalah bagian dari bahasa sejak itu ES2015

Contoh:

 
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
    
3
2016-04-12 20: 00: 46Z
  1. Saya kira banyak orang merujuk pertanyaan ini untuk mem-parsing input pengguna, yang biasanya berupa string . Jawaban ini gagal dalam kasus-kasus itu, karena Anda mencantumkan dengan benar dalam contoh, mis. Number.isFinite('0') -> false
    2016-04-12 19: 46: 50Z
  2. Anda sepenuhnya benar. Saya mencoba membuat ini jelas di muka.
    2016-04-12 20: 01: 44Z

Saya pikir fungsi parseFloat dapat melakukan semua pekerjaan di sini. Fungsi di bawah ini lulus semua tes pada halaman ini termasuk isNumeric(Infinity) == true:

 
function isNumeric(n) {

    return parseFloat(n) == n;
}
    
3
2018-10-01 09: 21: 48Z
  1. Ya, saya sampai pada kesimpulan ini juga. Saya juga cukup suka cara array diperlakukan menggunakan metode ini; array dengan nilai tunggal dianggap sebagai nilai itu, tetapi semuanya gagal: IsNumeric([3]) == true; IsNumeric([]) == false; IsNumeric([3, 4]) == false; Tapi saya bayangkan itu masalah selera!
    2016-08-31 11: 47: 41Z

Saya menggunakan solusi yang lebih sederhana:

 
function isNumber(num) {
    return parseFloat(num).toString() == num
}
    
2
2012-06-16 12: 25: 25Z
  1. ini akan gagal pada apa pun dengan 0 yang berlebihan pada akhirnya. contoh: "10.0"
    2012-09-28 22: 13: 33Z

Saya menyadari ini telah dijawab berkali-kali, tetapi berikut ini adalah kandidat yang layak yang dapat berguna dalam beberapa skenario.

harus dicatat bahwa ini mengasumsikan bahwa '.42' BUKAN angka, dan '4.' BUKAN angka, jadi ini harus diperhitungkan.

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

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

isDecimal lulus tes berikut:

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

Idenya di sini adalah bahwa setiap angka atau bilangan bulat memiliki satu representasi string "kanonik", dan setiap representasi non-kanonik harus ditolak. Jadi kami melemparkan ke nomor dan kembali, dan melihat apakah hasilnya adalah string asli.

Apakah fungsi ini bermanfaat bagi Anda tergantung pada use case. Salah satu fitur adalah bahwa string berbeda mewakili angka yang berbeda (jika keduanya lulus tes isNumber()).

Ini relevan, mis. untuk angka sebagai nama properti objek.

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

fungsi validasi perpustakaan knockoutJs

Dengan memperpanjangnya, bidang tersebut dapat divalidasi

1) angka

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

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 dan maks

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

Bidang ini hanya menerima nilai antara 5 dan 10

TestCase

 
numberValue = '5'    --> true
numberValue = '6'    --> true
numberValue = '6.5'  --> true
numberValue = '9'    --> true
numberValue = '11'   --> false
numberValue = '0'    --> false
numberValue = ''    --> false
    
2
2016-02-10 16: 17: 14Z

Anda dapat meminimalkan fungsi ini dengan banyak cara, dan Anda juga dapat menerapkannya dengan regex khusus untuk nilai negatif atau bagan khusus:

 
$('.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)
});
    
2
2017-02-23 15: 16: 43Z
 
function inNumeric(n){
   return Number(n).toString() === n;
}

Jika n adalah angka Number(n) akan mengembalikan nilai angka dan toString() akan mengubahnya kembali menjadi string. Tetapi jika n bukan numerik Number(n) akan mengembalikan NaN sehingga tidak cocok dengan yang asli n

    
2
2017-12-18 21: 28: 25Z
  1. Sementara cuplikan kode ini dapat menyelesaikan pertanyaan, including penjelasan benar-benar membantu meningkatkan kualitas posting Anda. Ingatlah bahwa Anda menjawab pertanyaan untuk pembaca di masa depan, dan orang-orang itu mungkin tidak tahu alasan untuk saran kode Anda. Harap juga mencoba untuk tidak membuat kerumunan kode Anda dengan komentar penjelasan, karena ini mengurangi keterbacaan kode dan penjelasan!
    2016-08-11 01: 11: 44Z

jawaban @CMS ': Cuplikan Anda gagal pada kasus spasi putih di komputer saya menggunakan nodejs. Jadi saya menggabungkannya dengan @ joel's jawaban ke yang berikut:

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

Saya mencabutnya dengan case yang mengapung:

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

dan kasing yang tidak mengapung (termasuk ruang kosong putih dan objek /array):

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

Semuanya berfungsi seperti yang diharapkan di sini. Mungkin ini membantu.

Kode sumber lengkap untuk ini dapat ditemukan di sini .

    
1
2017-05-23 12: 34: 53Z
sumber ditempatkan sini