Chciałbym, aby najprostszy niezawodny test sprawdził, czy ciąg w JavaScript jest dodatnią liczbą całkowitą.
isNaN(str)
zwraca true dla wszystkich rodzajów wartości niecałkowitych i parseInt(str)
zwraca liczby całkowite dla łańcuchów zmiennoprzecinkowych, takich jak „2.5”. Nie chcę też używać wtyczki jQuery.
javascript
Mick Byrne
źródło
źródło
isNaN()
Funkcja zachowuje się tak robi, bo to pojęcieNot a Number
ma bardzo konkretne znaczenie w pływającym punktem specyfikacji IEEE 794. Nie ma na celu udzielenia odpowiedzi na proste, potoczne pytanie: „czy ta wartość nie jest liczbą?”٢٣٤
czyMCMXIX
są zarówno ważne reprezentacjami całkowitymi, ale nie sądzę, szukasz kodu, który byłby zdolny do analizowania tych. Czy możesz określić, które formaty liczb będą obsługiwane, ponieważ ludzie wydają się być zdezorientowani.Odpowiedzi:
Dwie odpowiedzi dla ciebie:
Na podstawie analizy
Wyrażenie regularne
Zauważ, że w obu przypadkach zinterpretowałem „dodatnią liczbę całkowitą”, aby uwzględnić
0
, chociaż0
nie jest dodatnia. Załączam notatki, jeśli chcesz się nie zgadzać0
.Na podstawie analizy
Jeśli chcesz, aby był to znormalizowany dziesiętny ciąg liczb całkowitych w rozsądnym zakresie wartości, możesz to zrobić:
lub jeśli chcesz zezwolić na białe spacje i zera wiodące:
Aktywna platforma testowa (bez obsługi wiodących zer i białych znaków):
Pokaż fragment kodu
Aktywna platforma testowa ( z obsługą wiodących zer i białych znaków):
Pokaż fragment kodu
Jeśli chcesz zabronić
0
, po prostu zmień>= 0
na> 0
. (Lub w wersji, która pozwala na zera na początku, usuń znak|| "0"
wreplace
wierszu).Jak to działa:
W wersji ze spacjami i wiodącymi zerami:
str = str.trim();
usuwa wszelkie wiodące i końcowe białe znaki.if (!str)
łapie pusty ciąg i wraca, nie ma sensu wykonywać reszty pracy.str = str.replace(/^0+/, "") || "0";
usuwa wszystkie wiodące zera z ciągu - ale jeśli wynikiem jest pusty ciąg, przywraca pojedyncze 0.Number(str)
: Konwertujstr
na liczbę; liczba może również zawierać ułamek lub może byćNaN
.Math.floor
: Obetnij liczbę (odcina każdą część ułamkową).String(...)
: Konwertuje wynik z powrotem na normalny ciąg dziesiętny. W przypadku naprawdę dużych liczb przejdzie to do notacji naukowej, co może złamać to podejście. (Nie do końca wiem, gdzie jest podział, szczegóły podano w specyfikacji , ale wydaje mi się, że w przypadku liczb całkowitych przekroczyłeś 21 cyfr [do tego czasu liczba stała się bardzo nieprecyzyjna, ponieważ IEEE-754 Liczby o podwójnej precyzji mają tylko 15 cyfr dokładności ..)... === str
: Porównuje to do oryginalnego ciągu.n >= 0
: Sprawdź, czy to jest pozytywne.Zauważ, że nie powiedzie się to dla danych wejściowych
"+1"
, dowolnych danych w notacji naukowej, które nie zamieniają się z powrotem w tę samą notację naukową naString(...)
etapie, i dla każdej wartości, której używa rodzaj kodu JavaScript (zmiennoprzecinkowa podwójna precyzja IEEE-754) nie może dokładnie przedstawić, która parsuje jako bliżej innej wartości niż podana (która zawiera wiele liczb całkowitych powyżej 9 007,199,254,740,992; na przykład1234567890123456789
zawiedzie). Pierwsza z nich jest łatwa do rozwiązania, a druga nie tyle.Wyrażenie regularne
Drugim podejściem jest przetestowanie znaków ciągu za pomocą wyrażenia regularnego, jeśli Twoim celem jest po prostu (powiedzmy) opcjonalny ciąg,
+
po którym następuje jeden0
lub ciąg w normalnym formacie dziesiętnym:Live testbed:
Pokaż fragment kodu
Jak to działa:
^
: Dopasuj początek łańcucha\+?
: Zezwól na jeden, opcjonalny+
(usuń to, jeśli nie chcesz)(?:...|...)
: Zezwól na jedną z tych dwóch opcji (bez tworzenia grupy przechwytywania):(0|...)
: Pozwól0
sam ...(...|[1-9]\d*)
: ... lub liczbę rozpoczynającą się od czegoś innego niż,0
po której następuje dowolna liczba cyfr dziesiętnych.$
: Dopasuj koniec łańcucha.Jeśli chcesz zabronić
0
(ponieważ nie jest to pozytywne), wyrażenie regularne staje się po prostu/^\+?[1-9]\d*$/
(np. Możemy stracić alternatywę, na którą musieliśmy pozwolić0
).Jeśli chcesz, aby umożliwić zer (0123, 00524), a następnie po prostu zastąpić przemienności
(?:0|[1-9]\d*)
z\d+
Jeśli chcesz zezwolić na białe znaki, dodaj
\s*
tuż po^
i\s*
tuż przed$
.Uwaga: kiedy konwertujesz to na liczbę: w nowoczesnych silnikach prawdopodobnie dobrze byłoby użyć
+str
lubNumber(str)
zrobić to, ale starsze mogą rozszerzyć je w niestandardowy (ale wcześniej dozwolony) sposób, który mówi, że wiodące zero oznacza liczbę ósemkową (podstawa 8), np. „010” => 8. Po sprawdzeniu poprawności liczby można bezpiecznie użyć,parseInt(str, 10)
aby upewnić się, że jest ona przetwarzana jako dziesiętna (podstawa 10).parseInt
zignorowałby śmieci na końcu łańcucha, ale upewniliśmy się, że nie ma żadnego z wyrażeniem regularnym.źródło
Number(' ')
iNumber('')
wróć,0
podczas gdy powinny wrócićNaN
.parseInt
zwraca2
./\D/.test('2a')
jest prawdziwe (ponieważ nie ma cyfr). Więc możeif (!/\D/.test(str) && !isNan((num = parseInt(str, 10))) { /* Valid number in num */}
... Tuż po mojej głowie ...Rozwiązanie 1
Jeśli będziemy rozważać na całkowitą JavaScript jest wartość maksymalnej
4294967295
(tjMath.pow(2,32)-1
), a następnie po krótkim rozwiązanie doskonale pracy:OPIS:
123.45 >>> 0 === 123
-1 >>> 0 === 4294967295
MAX_INT
1e10 >>> 0 === 1410065408
1e7 >>> 0 === 10000000
parseFloat
poprawia parsowanie liczb ciągów (ustawienieNaN
dla ciągów nienumerycznych)TESTY:
DEMO: http://jsfiddle.net/5UCy4/37/
Rozwiązanie 2
Inny sposób jest dobry dla wszystkich wartości liczbowych, które są ważne do
Number.MAX_VALUE
, tj. Do około1.7976931348623157e+308
:OPIS:
!isNaN(parseFloat(n))
stosuje się do filtrowania czystych ciągów znaków, na przykład""
," "
,"string"
;0 <= ~~n
Filtry ujemnych i dużymi liczbami całkowitymi, na przykład"-40.1"
,"129000098131766699"
;(!isNaN(parseFloat(n)) && 0 <= ~~n)
zwraca,true
jeśli wartość jest zarówno liczbowa, jak i dodatnia ;0 === n % (...)
sprawdza, czy wartość nie jest zmiennoprzecinkowa - tutaj(...)
(patrz 3) jest obliczana jak0
w przypadkufalse
i jak1
w przypadkutrue
.TESTY:
DEMO: http://jsfiddle.net/5UCy4/14/
Poprzednia wersja:
DEMO: http://jsfiddle.net/5UCy4/2/
źródło
~~val
odcinanie części ułamkowej. Jest to nieco szybsze, ponieważ wykonuje jedną operację bitową zamiast dwóch.(!isNaN(parseFloat(n)) && n % 1 === 0 && 0 <= ~~n)
true, false, 0xFF
, a inne wartości przechodząisPositiveInteger
bez wykrycia.Wygląda na to, że należy zastosować wyrażenie regularne:
źródło
0
tam, gdzie normalnie byś się nie spodziewał, ale w większości wydaje się w porządku.Nowoczesne rozwiązanie, które działa w węźle i w ponad 90% wszystkich przeglądarek (oprócz IE i Opera Mini), polega na użyciu Number.isInteger, a następnie prostej kontroli pozytywnej.
Zostało to sfinalizowane w ECMAScript 2015 .
Polyfil to:
Jeśli potrzebujesz obsługi danych wejściowych w postaci ciągu lub liczby , możesz skorzystać z tej funkcji, dla której napisałem duży zestaw testów po tym, jak wszystkie istniejące odpowiedzi (2/1/2018) zawiodły w przypadku niektórych form wprowadzania.
źródło
To jest prawie duplikat tego pytania:
Sprawdź poprawność liczb dziesiętnych w JavaScript - IsNumeric ()
Odpowiedź brzmi:
więc dodatnią liczbą całkowitą byłoby:
źródło
nie zadziała, jeśli podasz ciąg taki jak „0001”
źródło
Moja funkcja sprawdza, czy liczba jest + ve i może mieć również wartość dziesiętną.
źródło
Aby skorzystać z powyższej odpowiedzi VisioN, jeśli używasz wtyczki sprawdzania poprawności jQuery, możesz użyć tego:
Następnie możesz użyć w swoim normalnym zestawie reguł lub dodać go dynamicznie w ten sposób:
źródło
Prosty
Możesz także rozszerzyć liczbę i przypisać do niej funkcję za pomocą prototypu.
źródło
Jeśli używasz formularzy HTML5, możesz użyć atrybutu
min="0"
elementu formularza<input type="number" />
. Jest to obsługiwane przez wszystkie główne przeglądarki. Nie wymaga Javascript dla tak prostych zadań, ale jest zintegrowany z nowym standardem HTML. Jest to udokumentowane na https://www.w3schools.com/tags/att_input_min.aspźródło
(~~a == a)
gdziea
jest ciąg.źródło
~~"-1" == "-1"
powrócitrue
. I OP poprosił tylko o dodatnie liczby całkowite.ES6:
źródło