(Wbudowany) sposób w JavaScript sprawdzania, czy ciąg znaków jest poprawną liczbą

Mam nadzieję, że jest coś w tej samej przestrzeni pojęciowej co stara funkcja VB6 IsNumeric()?

Author: Alexander Abakumov, 0000-00-00

19 answers

Aby sprawdzić, czy zmienna (w tym łańcuch znaków) jest liczbą, sprawdź, czy nie jest liczbą:

Działa to niezależnie od tego, czy zmienna zawiera ciąg znaków, czy liczbę.

isNaN(num)         // returns true if the variable does NOT contain a valid number

Przykłady

isNaN(123)         // false
isNaN('123')       // false
isNaN('1e10000')   // false (This translates to Infinity, which is a number)
isNaN('foo')       // true
isNaN('10px')      // true

Oczywiście, możesz to zaprzeczyć, jeśli chcesz. Na przykład, aby zaimplementować IsNumeric przykład, który podałeś:

function isNumeric(num){
  return !isNaN(num)
}

Aby przekonwertować łańcuch zawierający liczbę na liczbę:

Działa tylko wtedy, gdy łańcuch tylko zawiera znaki liczbowe, else zwraca NaN.

+num               // returns the numeric value of the string, or NaN 
                   // if the string isn't purely numeric characters

Przykłady

+'12'              // 12
+'12.'             // 12
+'12..'            // Nan
+'.12'             // 0.12
+'..12'            // Nan
+'foo'             // NaN
+'12px'            // NaN

Aby przekształcić łańcuch luźno na liczbę

Przydatne do konwersji '12px' na 12, na przykład:

parseInt(num)      // extracts a numeric value from the 
                   // start of the string, or NaN.

Przykłady

parseInt('12')     // 12
parseInt('aaa')    // NaN
parseInt('12px')   // 12
parseInt('foo2')   // NaN      These last two may be different
parseInt('12a5')   // 12       from what you expected to see. 

Pływaki

Należy pamiętać, że w przeciwieństwie do +num, parseInt (Jak sama nazwa wskazuje) przekonwertuje zmiennoprzecinkowy na liczbę całkowitą, odcinając wszystko po przecinku (jeśli chcesz użyć parseInt() z powodu tego zachowania, prawdopodobnie lepiej Ci będzie. użycie innej metody zamiast):

+'12.345'          // 12.345
parseInt(12.345)   // 12
parseInt('12.345') // 12

Puste ciągi

Puste ciągi mogą być nieco sprzeczne z intuicją. +num zamienia puste ciągi na zero, a isNaN() zakłada to samo:

+''                // 0
isNaN('')          // false

Ale parseInt() nie zgadza się:

parseInt('')       // NaN
 1723
Author: Dan,
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-11-28 15:47:16

I możesz przejść RegExp-way:

var num = "987238";

if(num.match(/^-{0,1}\d+$/)){
  //valid integer (positive or negative)
}else if(num.match(/^\d+\.\d+$/)){
  //valid float
}else{
  //not valid number
}
 36
Author: roenving,
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-11-30 22:16:17

Jeśli naprawdę chcesz się upewnić, że łańcuch zawiera tylko liczbę, dowolną liczbę (liczbę całkowitą lub zmiennoprzecinkową), a dokładnie liczbę, nie możesz użyć parseInt()/ parseFloat(), Number(), lub !isNaN() same. Zauważ, że {[6] } faktycznie zwraca true Kiedy Number() zwróci liczbę, a false kiedy zwróci NaN, więc wykluczę ją z reszty dyskusji.

Problem z parseFloat() polega na tym, że zwróci liczbę, jeśli łańcuch zawiera dowolną liczbę, nawet jeśli łańcuch nie zawiera tylko i dokładnie liczby:

parseFloat("2016-12-31")  // returns 2016
parseFloat("1-1") // return 1
parseFloat("1.2.3") // returns 1.2

Problem z Number() polega na tym, że zwróci liczbę w przypadkach, gdy przekazana wartość nie jest liczbą w ogóle!

Number("") // returns 0
Number(" ") // returns 0
Number(" \u00A0   \t\n\r") // returns 0

Problem z zwijaniem własnych wyrażeń regularnych polega na tym, że jeśli nie utworzysz dokładnych wyrażeń regularnych dla dopasowania liczby zmiennoprzecinkowej, Tak Jak rozpoznaje ją Javascript, przegapisz przypadki lub rozpoznasz przypadki, w których nie powinieneś. i nawet jeśli możesz zwijać własne wyrażenia regularne, dlaczego? Tam są prostsze wbudowane sposoby, aby to zrobić.

Okazuje się jednak, że Number() (i isNaN()) robi to dobrze dla każdego przypadku, w którym parseFloat() Zwraca liczbę, gdy nie powinna i odwrotnie. Aby dowiedzieć się, czy łańcuch jest rzeczywiście dokładnie i tylko liczbą, wywołaj obie funkcje i sprawdź, czy obie zwracają true:

function isNumber(str) {
  if (typeof str != "string") return false // we only process strings!
  // could also coerce to string: str = ""+str
  return !isNaN(str) && !isNaN(parseFloat(str))
}
 23
Author: Michael,
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-03-02 22:56:18

Jeśli próbujesz sprawdzić, czy łańcuch jest liczbą całkowitą( bez miejsc po przecinku), regex jest dobrym sposobem. Inne metody, takie jak isNaN są zbyt skomplikowane dla czegoś tak prostego.

function isNumeric(value) {
    return /^-{0,1}\d+$/.test(value);
}

console.log(isNumeric('abcd'));         // false
console.log(isNumeric('123a'));         // false
console.log(isNumeric('1'));            // true
console.log(isNumeric('1234567890'));   // true
console.log(isNumeric('-23'));          // true
console.log(isNumeric(1234));           // true
console.log(isNumeric('123.4'));        // false
console.log(isNumeric(''));             // false
console.log(isNumeric(undefined));      // false
console.log(isNumeric(null));           // false

Aby zezwolić tylko dodatnie liczby całkowite, użyj tego:

function isNumeric(value) {
    return /^\d+$/.test(value);
}

console.log(isNumeric('123'));          // true
console.log(isNumeric('-23'));          // false
 22
Author: Gavin,
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-11-30 22:15:27

Wypróbuj funkcję isNan :

Funkcja isNaN() określa, czy wartość jest liczbą nielegalną (nie-a-liczbą).

Funkcja zwraca true, jeśli wartość jest równa NaN. W przeciwnym razie zwraca false.

Ta funkcja różni się od liczby określonej Liczba.metoda isNaN().

Globalna funkcja isNaN (), zamienia badaną wartość na liczbę, a następnie ją testuje.

Liczba.isNan () nie konwertuje wartości do liczby i nie zwróci true dla żadnej wartości, która nie jest typu Number...

 20
Author: theraccoonbear,
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-06-15 16:15:09

Stare pytanie, ale w podanych odpowiedziach brakuje kilku punktów.

Notacja naukowa.

!isNaN('1e+30') jest true, jednak w większości przypadków, gdy ludzie pytają o liczby, nie chcą dopasować rzeczy takich jak 1e+30.

Duże liczby pływające mogą zachowywać się dziwnie

Observe (using Node."js"): {]}

> var s = Array(16 + 1).join('9')
undefined
> s.length
16
> s
'9999999999999999'
> !isNaN(s)
true
> Number(s)
10000000000000000
> String(Number(s)) === s
false
>

Z drugiej strony:

> var s = Array(16 + 1).join('1')
undefined
> String(Number(s)) === s
true
> var s = Array(15 + 1).join('9')
undefined
> String(Number(s)) === s
true
>

Więc, jeśli ktoś oczekuje String(Number(s)) === s, to lepiej ograniczyć swoje ciągi do 15 cyfr co najwyżej (po pominięciu zer wiodących).

Nieskończoność

> typeof Infinity
'number'
> !isNaN('Infinity')
true
> isFinite('Infinity')
false
>

Biorąc pod uwagę to wszystko, sprawdzając, czy dany ciąg znaków jest liczbą spełniającą wszystkie z następujących:

  • notacja nienaukowa
  • przewidywalna konwersja na Number i powrót do String
  • skończone

To nie takie łatwe zadanie. Oto prosta Wersja:

  function isNonScientificNumberString(o) {
    if (!o || typeof o !== 'string') {
      // Should not be given anything but strings.
      return false;
    }
    return o.length <= 15 && o.indexOf('e+') < 0 && o.indexOf('E+') < 0 && !isNaN(o) && isFinite(o);
  }

Jednak nawet ten jest daleki od ukończenia. Czołowe zera nie są tutaj obsługiwane, ale wkręcają test długości.

 10
Author: mark,
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-10-02 11:28:33

ParseInt (), ale należy pamiętać, że ta funkcja jest nieco inna w tym sensie, że na przykład zwraca 100 dla parseInt("100px").

 5
Author: liggett78,
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-10-06 19:16:22

Możesz użyć wyniku Liczby podczas przekazywania argumentu do jego konstruktora.

Jeśli argument (łańcuch znaków) nie może zostać przekonwertowany na liczbę, zwraca NaN, więc można określić, czy podany łańcuch był poprawną liczbą, czy nie.

Uwagi: Uwaga podczas przekazywania pustego ciągu znaków lub '\t\t' i '\n\t' jako liczba zwróci 0; przekazanie true zwróci 1, A false zwróci 0.

    Number('34.00') // 34
    Number('-34') // -34
    Number('123e5') // 12300000
    Number('123e-5') // 0.00123
    Number('999999999999') // 999999999999
    Number('9999999999999999') // 10000000000000000 (integer accuracy up to 15 digit)
    Number('0xFF') // 255
    Number('Infinity') // Infinity  

    Number('34px') // NaN
    Number('xyz') // NaN
    Number('true') // NaN
    Number('false') // NaN

    // cavets
    Number('    ') // 0
    Number('\t\t') // 0
    Number('\n\t') // 0
 5
Author: GibboK,
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-09-09 08:34:30

Być może jest jedna lub dwie osoby, które natkną się na to pytanie, które potrzebują bardziej rygorystycznego czeku niż zwykle (tak jak ja). W takim przypadku może to być przydatne:

if(str === String(Number(str))) {
  // it's a "perfectly formatted" number
}

Strzeż się! To odrzuci struny takie jak .1, 40.000, 080, 00.1. Jest to bardzo wybredne - ciąg musi pasować do "najbardziej minimalnej idealnej formy " liczby, aby ten test przeszedł.

Używa konstruktora String i Number do rzucania łańcucha na liczbę i z powrotem, a tym samym sprawdza, czy "Doskonała forma minimalna" silnika JavaScript (ta, do której został przekonwertowany za pomocą początkowego konstruktora Number) pasuje do oryginalnego ciągu znaków.

 5
Author: Joe,
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-01-09 10:57:15

Przetestowałem i rozwiązanie Michaela jest najlepsze. Zagłosuj na jego odpowiedź powyżej (wyszukaj na tej stronie "jeśli naprawdę chcesz upewnić się, że ciąg znaków", aby go znaleźć). W istocie, jego odpowiedź jest taka:

function isNumeric(num){
  num = "" + num; //coerce num to be a string
  return !isNaN(num) && !isNaN(parseFloat(num));
}

To działa dla każdego przypadku testowego, który udokumentowałem tutaj: https://jsfiddle.net/wggehvp9/5/

Wiele innych rozwiązań zawodzi w tych skrajnych przypadkach: '', null,"", true, oraz []. Teoretycznie można by ich użyć, przy odpowiedniej obsłudze błędów, dla przykład:

return !isNaN(num);

Lub

return (+num === +num);

Ze specjalną obsługą dla /\s/, null,"", true, false, [] (i inne?)

 5
Author: JohnP2,
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-21 01:06:17

Używam tego, który zrobiłem...

To działa do tej pory:

function checkNumber(value) {
    if ( value % 1 == 0 )
    return true;
    else
    return false;
}
Jeśli zauważysz jakiś problem, powiedz mi, proszę.
 4
Author: Rafael,
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-03-19 19:02:48

Cytat:

IsNaN (num) / / zwraca true jeśli zmienna nie zawiera poprawnej liczby

Nie jest do końca prawdą, jeśli musisz sprawdzić, czy nie ma spacji na początku/końcu - na przykład, gdy wymagana jest pewna ilość cyfr i musisz uzyskać, powiedzmy, "1111", a nie " 111 " lub " 111 " Dla być może wejścia PIN.

Lepiej używać:

var num = /^\d+$/.test(num)
 3
Author: Siubear,
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-01 05:31:14

Dlaczego implementacja jQuery nie jest wystarczająco dobra?

function isNumeric(a) {
    var b = a && a.toString();
    return !$.isArray(a) && b - parseFloat(b) + 1 >= 0;
};

Michael zasugerował coś takiego (chociaż ukradłem tu zmienioną wersję "user1691651-John"):

function isNumeric(num){
    num = "" + num; //coerce num to be a string
    return !isNaN(num) && !isNaN(parseFloat(num));
}

Poniżej znajduje się rozwiązanie o najprawdopodobniej złej wydajności, ale solidnych wynikach. Jest to ustrojstwo wykonane z implementacji jQuery 1.12.4 i odpowiedzi Michaela, z dodatkowym sprawdzeniem dla spacji wiodących / końcowych (ponieważ Wersja Michaela zwraca true dla liczb z wiodącymi/końcowymi spacje): {]}

function isNumeric(a) {
    var str = a + "";
    var b = a && a.toString();
    return !$.isArray(a) && b - parseFloat(b) + 1 >= 0 &&
           !/^\s+|\s+$/g.test(str) &&
           !isNaN(str) && !isNaN(parseFloat(str));
};

Ta ostatnia wersja ma jednak dwie nowe zmienne. Można obejść jedną z nich, wykonując:

function isNumeric(a) {
    if ($.isArray(a)) return false;
    var b = a && a.toString();
    a = a + "";
    return b - parseFloat(b) + 1 >= 0 &&
            !/^\s+|\s+$/g.test(a) &&
            !isNaN(a) && !isNaN(parseFloat(a));
};

Nie testowałem żadnego z nich za bardzo, innymi metodami niż ręczne testowanie kilku przypadków użycia, które będę uderzać z moim obecnym kłopotem, co jest bardzo standardową rzeczą. Jest to sytuacja" stojąca na ramionach gigantów".

 3
Author: Ultroman the Tacoman,
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-15 13:25:45

PFB rozwiązanie robocze:

 function(check){ 
    check = check + "";
    var isNumber =   check.trim().length>0? !isNaN(check):false;
    return isNumber;
    }
 1
Author: Predhin,
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-04-30 13:32:00

Moja próba nieco mylącego, Pherhaps nie jest najlepszym rozwiązaniem

function isInt(a){
    return a === ""+~~a
}


console.log(isInt('abcd'));         // false
console.log(isInt('123a'));         // false
console.log(isInt('1'));            // true
console.log(isInt('0'));            // true
console.log(isInt('-0'));           // false
console.log(isInt('01'));           // false
console.log(isInt('10'));           // true
console.log(isInt('-1234567890'));  // true
console.log(isInt(1234));           // true
console.log(isInt('123.4'));        // false
console.log(isInt(''));             // false

// other types then string returns false
console.log(isInt(5));              // false
console.log(isInt(undefined));      // false
console.log(isInt(null));           // false
console.log(isInt('0x1'));          // false
console.log(isInt(Infinity));       // false
 1
Author: Endless,
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-09-12 16:07:38

Jeśli ktoś się tak zagłębi, spędziłem trochę czasu na hakowaniu tego, próbując załagodzić moment.js ( https://github.com/moment/moment ). Oto coś, co mu odebrałem:

function isNumeric(val) {
    var _val = +val;
    return (val !== val + 1) //infinity check
        && (_val === +val) //Cute coercion check
        && (typeof val !== 'object') //Array/object check
}

Obsługuje następujące przypadki:

Prawda! :
isNumeric("1"))
isNumeric(1e10))
isNumeric(1E10))
isNumeric(+"6e4"))
isNumeric("1.2222"))
isNumeric("-1.2222"))
isNumeric("-1.222200000000000000"))
isNumeric("1.222200000000000000"))
isNumeric(1))
isNumeric(0))
isNumeric(-0))
isNumeric(1010010293029))
isNumeric(1.100393830000))
isNumeric(Math.LN2))
isNumeric(Math.PI))
isNumeric(5e10))
False! :
isNumeric(NaN))
isNumeric(Infinity))
isNumeric(-Infinity))
isNumeric())
isNumeric(undefined))
isNumeric('[1,2,3]'))
isNumeric({a:1,b:2}))
isNumeric(null))
isNumeric([1]))
isNumeric(new Date()))
Jak na ironię, z którym zmagam się najbardziej:
isNumeric(new Number(1)) => false
Wszelkie sugestie mile widziane. :]
 1
Author: The Dembinski,
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-01-04 07:37:09

Podoba mi się ta prostota.

Number.isNaN(Number(value))

Powyższe jest zwykłym Javascript, ale używam tego w połączeniu z typescript typeguard do inteligentnego sprawdzania typów. Jest to bardzo przydatne dla kompilatora maszynopisu, aby dać ci poprawne intellisense i żadnych błędów typu.

Typescript typeguards

isNotNumber(value: string | number): value is string {
    return Number.isNaN(Number(this.smartImageWidth));
}
isNumber(value: string | number): value is number {
    return Number.isNaN(Number(this.smartImageWidth)) === false;
}

Powiedzmy, że masz własność width, która jest number | string. Możesz zrobić logikę w oparciu o to, czy jest to ciąg znaków.

var width: number|string;
width = "100vw";

if (isNotNumber(width)) 
{
    // the compiler knows that width here must be a string
    if (width.endsWith('vw')) 
    {
        // we have a 'width' such as 100vw
    } 
}
else 
{
    // the compiler is smart and knows width here must be number
    var doubleWidth = width * 2;    
}

Typeguard jest wystarczająco inteligentny, aby ograniczyć typ width w if, aby był tylko string. Pozwala to kompilatorowi zezwalać width.endsWith(...), na co nie pozwalałby, gdyby typ był string | number.

Możesz nazywać typeguard jak chcesz isNotNumber, isNumber, isString, isNotString ale myślę, że {[12] } jest niejednoznaczna i trudniejsza do odczytania.

 1
Author: Simon_Weaver,
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-27 07:30:39

W mojej aplikacji dopuszczamy tylko a-z A-Z i 0-9 znaków. Odpowiedź znalazłem powyżej używając "string % 1 === 0" działa, chyba że łańcuch zaczynał się od 0xnn (np. 0x10) i wtedy zwracałby go jako liczbę, gdy nie chcieliśmy tego robić. Poniższa prosta pułapka w moim sprawdzeniu numerycznym wydaje się działać w naszych konkretnych przypadkach.

function isStringNumeric(str_input){   
    //concat a temporary 1 during the modulus to keep a beginning hex switch combination from messing us up   
    //very simple and as long as special characters (non a-z A-Z 0-9) are trapped it is fine   
    return '1'.concat(str_input) % 1 === 0;}

Warning: to może być wykorzystanie długotrwałego błędu w Javascript i Actionscript [Number("1" + the_string) % 1 = = = 0)], nie mogę tego powiedzieć, ale to jest dokładnie to, czego potrzebowaliśmy.

 0
Author: rwheadon,
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-07-08 15:22:23
 
Author: ,
Warning: date() expects parameter 2 to be long, string given in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54