JavaScript'te ondalık sayıları doğrulama - IsNumeric ()


2376

JavaScript'te ondalık sayıları doğrulamanın en temiz ve etkili yolu nedir?

Bonus puanları:

  1. Açıklık. Çözüm temiz ve basit olmalıdır.
  2. Çapraz platform.

Test senaryoları:

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

256
Sadece bir not 99,999 Fransa'da geçerli bir sayıdır, uk / us formatında 99.999 ile aynıdır, bu nedenle bir giriş formundan dize okuyorsanız 99,999 doğru olabilir.
Re0sless


79
Ondalık virgül tüm Avrupa ve Rusya'da standarttır (İngiltere hariç)
Calmarius

90
jQuery 1.7 jQuery.isNumericyardımcı işlevini tanıttı : api.jquery.com/jQuery.isNumeric
Ates Goral

24
jQuery.isNumericOP'nin yedinci test senaryosunda ( IsNumeric('0x89f') => *false*) başarısız olur . Ancak bu test senaryosuna katılıp katılmadığımdan emin değilim.
Tim Lehner

Yanıtlar:


2898

@ Joel'in yanıtı oldukça yakın, ancak aşağıdaki durumlarda başarısız olacaktır:

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

Bir uygulamak zorunda olduğu süre önce IsNumericişlevini değişken sayısal bir değer içeriyorsa, öğrenmek için cinsine bakılmaksızın , bu bir olabilir Stringsayısal bir değer (ı vb, üstel gösterimi, dikkate almak zorunda) içeren bir Numbernesne, hemen hemen her şey bu işleve geçirilebilirdi, tip zorlamasıyla ilgilenen herhangi bir tip varsayımı yapamadım (örneğin, +true == 1;ancak trueolarak düşünülmemelidir "numeric").

Bence çok sayıda fonksiyon uygulamasına yapılan bu +30 birim testi setini paylaşmaya değer ve ayrıca tüm testlerimi geçen testi paylaşmaya değer:

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

PS isNaN & isFinite , sayıya zorla dönüştürme nedeniyle kafa karıştırıcı bir davranışa sahiptir. ES6'da Number.isNaN & Number.isFinite bu sorunları giderir. Bunları kullanırken bunu aklınızda bulundurun.


Güncelleme : İşte jQuery bunu nasıl yapıyor (2.2 kararlı) :

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

Güncelleme : Açısal 4.3 :

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

26
bu, ondalık virgül kullandığımız diğer yerel ayarlarla başarısız olur, ancak `n = n.replace (/, /,". "); düzeltmek için geri dönmeden önce.
Zoltan Lengyel

5
@RobG, bu davranış kasıtlı, 2e308 > Number.MAX_VALUEçünkü 2e308 == Infinity. truePozitif ve negatif sonsuzluk değerleri için de geri dönen bir fonksiyon istiyorsanız , test takımında 2 numaralı fonksiyonu kontrol edin . Şerefe.
CMS

39
Bu arada, birim testleri şu anda jQuery projesi
CMS

7
jQuery şimdi de bu uygulamayı kullanıyor .
RichardTowers

4
Buradaki çözüm sadece JQuery kullanmaktır. Şimdi bunun daha iyi bir uygulaması var: github.com/jquery/jquery/blob/master/src/core.js#L230
Robert Massaioli

337

Arrrgh! Normal ifade cevaplarını dinlemeyin. RegEx bu konuda icky ve sadece performanstan bahsetmiyorum. Normal ifadenizle hataları tespit etmek için ince, imkansız hale getirmek çok kolay.

Kullanamıyorsanız isNaN(), bu çok daha iyi çalışmalıdır:

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

Şöyle çalışır:

(input - 0)İfadesi, giriş değerine tip zorlama yapmak için JavaScript zorlar; önce çıkarma işlemi için bir sayı olarak yorumlanmalıdır. Bir sayıya dönüştürme başarısız olursa, ifade ile sonuçlanır NaN. Bu sayısal sonuç daha sonra ilettiğiniz orijinal değerle karşılaştırılır. Sol taraf artık sayısal olduğundan, baskı türü tekrar kullanılır. Artık her iki taraftan gelen girdi, aynı orijinal değerle aynı türe zorlandığına göre, her zaman aynı olmaları gerektiğini düşünürdünüz (her zaman doğru). Ancak, NaNasla eşit olmayan özel bir kural vardır NaNve bu nedenle bir sayıya dönüştürülemeyen bir değer (ve yalnızca sayılara dönüştürülemeyen değerler) yanlış ile sonuçlanır.

Uzunluk kontrolü boş telleri içeren özel bir durum içindir. Ayrıca, 0x89f testinize düştüğünü unutmayın, ancak bunun nedeni birçok ortamda bir sayı değişmezini tanımlamanın iyi bir yoludur. Bu senaryoyu yakalamak istiyorsanız, ek bir kontrol ekleyebilirsiniz. Daha da iyisi, kullanmamanızın nedeni buysa , ek kontrol yapabilen isNaN()kendi işlevinizi sarın isNaN().

Özetle, bir değerin bir sayıya dönüştürülüp dönüştürülemeyeceğini bilmek istiyorsanız, bunu aslında bir sayıya dönüştürmeyi deneyin.


Geri döndüm ve neden bir boşluk dizesinin beklenen çıktıya sahip olmadığı için biraz araştırma yaptım ve şimdi anladım: boş bir dize 0yerine zorlanıyor NaN. Uzunluk kontrolünden önce ipi basitçe kesmek bu durumu ele alacaktır.

Ünite testlerini yeni koda karşı çalıştırmak ve sadece sonsuzluk ve boole değişmezlerinde başarısız olur ve sorun olması gereken tek zaman kod oluşturuyorsanız (gerçekten, bir değişmez yazacak ve sayısal olup olmadığını kim kontrol edecek? Sen gerektiğini biliyorum ) ve bazı garip kod üretmek olacaktır.

Ancak, yine de, bunu kullanmanın tek nedeni, bir nedenden kaçınmanız gerektiğidir.NaN ().


28
Bu boşluk gibi dizeleri başarısız, örneğin IsNumeric(' '), IsNumeric('\n\t')vb tüm dönüyortrue
Crescent Fresh

29
Ayrıca üzerinde başarısız olur Numberdeğişmezleri IsNumeric(5) == false;ben yayınlanmıştır birim testlerinin setini kontrol, bu fonksiyon sayıdır 16test paketi üzerinde. stackoverflow.com/questions/18082/…
CMS

20
Hiç kimsenin, düzenli ifadeler kullanmama konusunda uyarı yaptıktan sonra düzenli ifadenin (yerine koyulduğunu) işaret ettiğine inanamıyorum ... Verilen bir boşluk boşluğunun bir sayı ayrıştırmasından daha basit olduğunu, ancak yine de kesinlikle "icky" olduğunu.
Patrick M

1
@Oriol Bu büyük bir sorun ... o tarihten sonra hiçbir güvenlik düzeltmesi yayınlanmadığında, XP'den uzaklaşmak bir öncelik olmalı.
Joel Coehoorn

1
@Oriol XP ya da değil, IE8 ya da daha düşük bir sürüm kullanıyorsanız, son derece güncel olmayan bir yazılım kullanıyorsunuz. Verilen XP IE9 + 'yı çalıştıramaz, bu nedenle Chrome veya FF kullanın. Geçmişte IE8 kullanarak yaşayan insanlar, birçok web geliştiricisinin varlığının sıkıntısıdır. Ben mükemmel iyi bir kod da IE8 çalışır emin olmak için harcadım zaman geri olabilir ... Bana FF ve Chrome çalışan kod alma ve IE8 çalıştırmak için yama yama bir windows 8 yürütülebilir alarak pratik hakkında Windows 3.1'de aynı şekilde çalıştığından emin olmak.
chiliNUT

70

Bu şekilde iyi çalışıyor gibi görünüyor:

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

Bir satırda:

const IsNumeric = (num) => /^-{0,1}\d*\.{0,1}\d+$/.test(num);

Ve test etmek için:

const IsNumeric = (num) => /^-{0,1}\d*\.{0,1}\d+$/.test(num);
    
    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;
    }

console.log(TestIsNumeric());
.as-console-wrapper { max-height: 100% !important; top: 0; }

Bu normal ifadeyi http://www.codetoad.com/javascript/isnumeric.asp adresinden ödünç aldım . Açıklama:

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

1
// AYRICA TEST sonuçlarınıza EKLENMELİ + = (! IsNumeric ('-')? "Pass": "Fail") + ": IsNumeric ('-') => false \ n"; results + = (! IsNumeric ('01 ')? "Pass": "Fail") + ": IsNumeric ('01') => false \ n"; results + = (! IsNumeric ('- 01')? "Pass": "Fail") + ": IsNumeric ('- 01') => false \ n"; results + = (! IsNumeric ('000')? "Pass": "Fail") + ": IsNumeric ('000') => false \ n";
Dan

bu ne yapar? / ^ - {0,1} \ d * \. {0,1} \ d + $ /
call-me

"{0,1}", "?" ile değiştirilebilir, böylece normal ifadeniz şu şekilde görünecektir: /^-?\d*\.?\d+$/?
Bulut

güzel ve basit.
kırıcı

53

Yahoo! Kullanıcı arayüzü bunu kullanır:

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

25
Bu, sayının içeriğinin aksine değişken türünü daha kontrol eder. Ayrıca, ile oluşturulan numaralarda da başarısız olur new Number(1).
alex

4
Alex'in dediği gibi, bu aslında sorulan soruya cevap vermez, çünkü o = "1001" olursa başarısız olur.
Dava

50
function IsNumeric(num) {
     return (num >=0 || num < 0);
}

Bu 0x23 tip numaraları için de geçerlidir.


29
IsNumeric(''), IsNumeric(' '), IsNumeric(true), IsNumeric(false), IsNumeric(null)Dönmek trueyerine false.
Oriol

49

Kabul edilen cevap 7 numaralı sınavda başarısız oldu ve sanırım bunun nedeni fikrini değiştirmen. Bu, kabul ettiğim cevaba bir cevap, benim sorunlarım vardı.

Bazı projeler sırasında bazı verileri doğrulamam ve matematiksel işlemlerde kullanılabilecek bir javascript sayısal değeri olduğundan olabildiğince emin olmam gerekiyordu.

jQuery ve diğer bazı javascript kitaplıkları zaten genellikle denilen böyle bir işlevi içerir isNumeric. Yığın akışı üzerinde, daha önce bahsedilen kütüphanelerin kullandığı genel rutin olan cevap olarak yaygın olarak kabul edilen bir yazı da vardır .

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

İlk olarak, bağımsız değişken 1 uzunluk dizisi olsaydı ve bu tek eleman yukarıdaki mantık tarafından sayısal olarak kabul edilen bir türdeyse yukarıdaki kod true değerini döndürür. Bence bu bir dizi ise sayısal değildir.

Bu sorunu hafifletmek için, mantıktaki dizileri indirim için bir kontrol ekledim

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

Tabii ki, aynı zamanda kullanabilir Array.isArray, jquery $.isArrayveya prototip Object.isArrayyerineObject.prototype.toString.call(n) !== '[object Array]'

İkinci sorunum, Negatif Onaltılık tam sayı değişmez dizelerinin ("-0xA" -> -10) sayısal olarak sayılmamasıydı. Ancak, Pozitif Onaltılık tam sayı değişmez dizeleri ("0xA" -> 10) sayısal olarak işlem gördü. Her ikisinin de geçerli sayısal olması gerekiyordu.

Daha sonra bunu hesaba katmak için mantığı değiştirdim.

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

İşlev her çağrıldığında normal ifadenin oluşturulmasından endişe ediyorsanız, bir kapatma içinde yeniden yazabilirsiniz, böyle bir şey

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

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

Daha sonra CMSs +30 test vakalarını aldım ve jsfiddle üzerinde yapılan testleri klonladım, ekstra test vakalarımı ve yukarıda açıklanan çözümümü ekledim.

Yaygın olarak kabul edilen / kullanılan cevabın yerine geçmeyebilir, ancak bu daha fazla isNumeric fonksiyonunuzun sonuçları olarak beklediğinizden daha fazla ise, umarım bu biraz yardımcı olacaktır.

EDIT: Bergi'nin işaret ettiği gibi , sayısal olarak kabul edilebilecek diğer olası nesneler de var ve beyaz listeye kara listeden daha iyi olurdu. Bunu göz önünde bulundurarak kriterlere katkıda bulunacağım.

Benim isNumeric işlevi yalnızca Sayılar veya Dizeleri dikkate almak istiyorum

Bunu göz önünde bulundurarak, kullanmak daha iyi olurdu

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

Çözümleri test edin

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>


2
Benim görüşüme göre bu en korumalı işlev; sonuncu. Kabul edilen cevap muhtemelen tüm vakaların% 99,99'unu kapsamaktadır, ancak bu sorunun a) küçük bir ek yükü olan vakaların muhtemelen% 100'ü vardır.
Samuel

"99,999" Kayar Nokta hazır bilgisini unuttun. İngiltere
hariç

OP unutulmadı, Javascript sayıları anlamında sayısal olarak düşündüğüm bir şey değildi, OP de şunları söylediIsNumeric('99,999') => false
Xotic750

34

Evet, yerleşik isNaN(object)olan herhangi bir normal ifade ayrıştırmasından çok daha hızlı olacaktır, çünkü anında yorumlanmak yerine yerleşik ve derlenmiştir.

Sonuçlar aradığınızdan biraz farklı olsa da ( deneyin ):

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

18

İşlevi kullanın isNaN. Test ederseniz !isNaN(yourstringhere), bu durumlardan herhangi biri için iyi çalışıyor inanıyorum .


Not:! İsNaN (null) == Sayı (null) == 0'dan beri doğru
Jonathan Lonowski

if (! (x == null || isNaN (x))) alert ("isNumeric"); // Ama bu çözüm 0x40'ı kabul ettiğinden op'un istediği hala bu değil.
bazı

İsNaN ("Infinity") === false değerine dikkat edin, bu da muhtemelen istediğiniz şey değildir (ancak gerçek hayatta da olmayacaktır).
Erik Hesselink

16

JQuery 1.7'den beri şunları kullanabilirsiniz jQuery.isNumeric():

$.isNumeric('-1');      // true
$.isNumeric('-1.5');    // true
$.isNumeric('0');       // true
$.isNumeric('0.42');    // true
$.isNumeric('.42');     // true
$.isNumeric('0x89f');   // true (valid hexa number)
$.isNumeric('99,999');  // false
$.isNumeric('#abcdef'); // false
$.isNumeric('1.2.3');   // false
$.isNumeric('');        // false
$.isNumeric('blah');    // false

Söylediklerinizin aksine 0x89fgeçerli bir sayı (hexa) olduğunu unutmayın.


OP geçerli ondalık sayı istiyor , bu nedenle jQuery isNumeric uymuyor. Ayrıca çok büyük sayılar için başarısız olur.
RobG

13

RegExp olmadan yapılabilir

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

5
== kullanırsak, dize olarak sunulan sayılar için bile true değerini döndürür. Bu nedenle "42", "==" durumunda geçerli sayı olarak sayılır ve ===
Aquatic

bu "-0.", "-.0", ".0" ve "0" harflerinde true değerini döndürür.
Janus Troelsen


8
return (input - 0) == input && input.length > 0;

benim için çalışmadı. Ne zaman bir uyarı koymak ve test, input.lengtholdu undefined. Tamsayı uzunluğunu kontrol etmek için hiçbir özellik olmadığını düşünüyorum. Yani yaptığım şey

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

İyi çalıştı.


7

Yanılmıyorsam, bu sabitler ( Infinity, NaN) ve işaret operatörleri +/ hariç herhangi bir geçerli JavaScript numarası değeriyle eşleşmelidir -(çünkü aslında ilgili sayının bir parçası olmadığından, ayrı işleçlerdir):

Bu numarayı değerlendirme için JavaScript'e göndermenin bir seçenek olmadığı bir belirteç için buna ihtiyacım vardı ... Kesinlikle mümkün olan en kısa düzenli ifade değil, ancak JavaScript'in numara sözdiziminin tüm ince inceliklerini yakaladığına inanıyorum.

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

Geçerli sayılar şunları içerir:

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

Geçersiz sayılar

 - 00e1
 - 01e1
 - 00.0
 - 00x0
 - .
 - .e0

7

@ CMS'nin cevabı ile yaşadığım tek sorun NaN, birçok durum için yararlı sayılar olan dışlama ve Infinity'dir. NaN'Leri kontrol etmenin bir yolu, kendilerine eşit olmayan sayısal değerleri kontrol etmektir NaN != NaN! Bu yüzden uğraşmak istediğiniz 3 test var ...

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

Benim isComparableNumber başka bir zarif cevaba oldukça yakın , ancak hex ve sayıların diğer dize temsillerini işler.


6

Bana göre bu en iyi yol:

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

Ne yazık ki, bu "0" vb. Gibi yalnızca sayısal harfler içeren herhangi bir dize için başarısız olacak tür bir STRICT sayısal denetleyicidir ...
Arman McHitarian

6

Aşağıdakileri eklemek istiyorum:

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

Pozitif onaltılık sayılar ile başlar 0xve negatif onaltılı sayılar ile başlar -0x. Pozitif okt sayıları ile başlar 0ve negatif okt sayıları ile başlar -0. Bu, daha önce bahsedilenlerin çoğunu alır, ancak onaltılık ve sekizli sayıları, negatif bilimsel, Sonsuzluğu içerir ve ondalık bilimselleri kaldırmıştır ( 4e3.2geçerli değildir).

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

6

Bence parseFloat işlevi burada tüm işleri yapabilir. Aşağıdaki işlev, bu sayfadaki tüm testleri geçer isNumeric(Infinity) == true:

function isNumeric(n) {

    return parseFloat(n) == n;
}

Evet, ben de bu sonuca vardım. Ben de diziler bu yöntemi kullanarak tedavi şekli oldukça seviyorum; tek bir değere sahip bir dizi bu değer olarak sayılır, ancak her şey başarısız olur: IsNumeric([3]) == true; IsNumeric([]) == false; IsNumeric([3, 4]) == false; Ama bunun bir zevk meselesi olduğunu hayal ediyorum!
Mark Birbeck

4

Eklenecek birkaç test:

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

Ben bununla geldim:

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

Çözüm şunları kapsar:

  • Başlangıçta isteğe bağlı bir negatif işaret
  • Tek bir sıfır veya 0 ile başlamamış bir veya daha fazla basamak veya bir süre takip ettiği sürece hiçbir şey
  • Ardından 1 veya daha fazla sayı olan bir nokta

4

Bir tamsayı değeri şu şekilde doğrulanabilir:

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

Bu şekilde daha kolay ve daha hızlı! Tüm testler kontrol edilir!


4

İşte tam jQuery varyantı yerine kullandığım bir lil bit geliştirilmiş versiyonu (muhtemelen en hızlı yolu), gerçekten neden bunu kullanmıyorlar bilmiyorum:

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

JQuery'nin versiyonunun olumsuz sayısal değerler lider ve benzeri harfleri sondaki bir dize geçirirseniz olmasıdır dışarı sayısal kısmını ayıklamak ve 123 dönmek ANCAK olacak, ikinci muhafız yine de başarısız olur. Tekli operatör ile ilk bekçide ölecek, çünkü + bu tür melezler için NaN atıyor :) Biraz performans henüz sağlam bir semantik kazanç olduğunu düşünüyorum."123abc"parseFloat | parseIntisFinite+


2
Bir nesnenin üzerindeki '+' değerinin çağrılmasına neden olacak tek noktaya dikkat edin - bu jsfiddle'a bakın . Ayrıca bu, önde gelen cevapta olduğu gibi, önde gelen boşluk için de başarısız olur.
earcam

3

Çözümüm,

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

Her durumda çalışıyor gibi görünüyor, ama yanılmış olabilirim.


Eğer gereksiz karakterler, kullanımını kaçmadı eğer bu regex daha az kafa karıştırıcı olacağını ?için {0,1}ve \diçin [0-9]. Ayrıca +ve sonra onu sararak (yakalamayan) grupları (?:){0,1}da kullanabilir *ve unutabilirsiniz.
alex

3

Daha basit bir çözüm kullanıyorum:

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

5
bu, sonunda gereksiz 0'lar olan herhangi bir şeyde başarısız olacaktır. örnek: "10.0"
Janus Troelsen

3

Bu çalışmalı. Burada sağlanan işlevlerin bazıları kusurludur, ayrıca buradaki diğer işlevlerden daha hızlı olmalıdır.

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

Açıklaması:

Kendisinin bir kopyasını oluşturun, sonra sayıyı kayan noktaya dönüştürür, sonra hala bir sayı ise (tamsayı veya kayan nokta) orijinal numarayla karşılaştırır ve orijinal sayı ile eşleşir, yani gerçekten bir sayıdır.

Düz sayıların yanı sıra sayısal dizelerle de çalışır. Onaltılık sayılarla çalışmaz.

Uyarı: kendi sorumluluğunuzdadır kullanın, garanti yok.


4
Kendi sorumluluğunuzdadır, garanti yok Yazarın kendinden emin olmadığı kodu kullanmam;)
alex

1
@Alex, En azından şeyler hakkında kendi fikrin var. Sadece her zaman eleştirme.
Stewart Mbofana

3

Cevapların hiçbiri falseboş dizgiler için geri dönmez , bunun için bir düzeltme ...

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

3

Bir değişkenin yalnızca sayıya benzeyen bir String değil, geçerli bir sayı içerip içermediğini kontrol etmek Number.isFinite(value)için kullanılabilir.

Bu, ES2015'ten bu yana dilin bir parçası

Örnekler:

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
Birçok kişi, genellikle bir dize olacak kullanıcı girişi ayrıştırma için bu soruya bakın sanırım . Örneklerde doğru bir şekilde listelediğiniz gibi, bu cevap başarısız olur, örneğinNumber.isFinite('0') -> false
Michael Haren

Tamamen haklısın. Bunu netleştirmeye çalıştım.
adius

3
function inNumeric(n){
   return Number(n).toString() === n;
}

N sayısalsa Number(n) , sayısal değeri döndürür ve toString()bir dizeye geri döndürür. Ancak n sayısal değilse, orijinal ile eşleşmeyecek Number(n)şekilde geri dönerNaNn


Bu kod snippet'i soruyu çözebilir, ancak bir açıklama da dahil olmak üzere , yayınınızın kalitesini artırmaya yardımcı olur. Gelecekte okuyucular için soruyu cevapladığınızı ve bu kişilerin kod önerinizin nedenlerini bilmeyebileceğini unutmayın. Lütfen hem kodun hem de açıklamaların okunabilirliğini azalttığı için kodunuzu açıklayıcı yorumlarla doldurmamaya çalışın!
Güle güle StackExchange

2

Bunun birçok kez yanıtlandığını anlıyorum, ancak aşağıdaki bazı senaryolarda yararlı olabilecek iyi bir aday.

'.42' nin bir sayı DEĞİL ve '4' olduğunu varsaydığı unutulmamalıdır. bir sayı DEĞİLDİR, bu nedenle bu dikkate alınmalıdır.

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

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

isDecimalAşağıdaki test geçer:

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

Buradaki fikir, her sayı veya tamsayının bir "kanonik" dize temsiline sahip olması ve her kanonik olmayan temsilin reddedilmesi gerektiğidir. Bu yüzden bir sayıya geri dönüyoruz ve sonucun orijinal dize olup olmadığını görüyoruz.

Bu işlevlerin sizin için yararlı olup olmadığı kullanım durumuna bağlıdır. Bir özellik, farklı dizelerin farklı sayıları temsil etmesidir (her ikisi de isNumber()testi geçerse ).

Bu, örneğin nesne özellik adları olarak sayılarla ilgilidir.

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

2

knockoutJs Kitaplık doğrulama işlevlerini oluşturma

Alan genişletilerek onaylanır

1) sayı

self.number = ko.observable(numberValue).extend ({sayı: doğru}) ;

Test durumu

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

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

Test durumu

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 ve maks.

self.number = ko.observable(numberValue).extend ({dk: 5}). uzatın ({max: 10}) ;

Bu alan yalnızca 5 ile 10 arasındaki değeri kabul eder

Test durumu

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

2

Özel bir ondalık sayı kümesini doğrulamanız gerekiyorsa, bu basit javascript'i kullanabilirsiniz:

http://codesheet.org/codesheet/x1kI7hAD

<input type="text" name="date" value="" pattern="[0-9]){1,2}(\.){1}([0-9]){2}" maxlength="6" placeholder="od npr.: 16.06" onchange="date(this);" />

Javascript:

function date(inputField) {        
  var isValid = /^([0-9]){1,2}(\.){1}([0-9]){2}$/.test(inputField.value);   
  if (isValid) {
    inputField.style.backgroundColor = '#bfa';
  } else {
    inputField.style.backgroundColor = '#fba';
  }
  return isValid;
}

2

isNumeric=(el)=>{return Boolean(parseFloat(el)) && isFinite(el)}

Çok farklı bir şey yok ama Boolean yapıcısını kullanabiliriz

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.