Saya ingin tes gagal-aman yang paling sederhana untuk memeriksa apakah string dalam JavaScript adalah bilangan bulat positif.
isNaN(str)
mengembalikan true untuk semua jenis nilai non-integer dan parseInt(str)
mengembalikan integer untuk string float, seperti "2.5". Dan saya tidak mau harus menggunakan beberapa plugin jQuery juga.
javascript
Mick Byrne
sumber
sumber
isNaN()
Fungsi berperilaku jalan tersebut karena konsepnyaNot a Number
memiliki arti yang sangat spesifik dalam IEEE 794 floating spesifikasi titik. Itu tidak bermaksud memberikan jawaban untuk pertanyaan sehari-hari yang sederhana, "apakah nilai ini bukan angka?"٢٣٤
atauMCMXIX
keduanya adalah representasi integer yang valid, tetapi saya tidak berpikir Anda sedang mencari kode yang dapat menguraikan ini. Bisakah Anda menentukan format angka yang akan Anda dukung, karena orang-orang tampaknya bingung tentang hal itu.Jawaban:
Dua jawaban untuk Anda:
Berdasarkan parsing
Ekspresi reguler
Perhatikan bahwa dalam kedua kasus, saya telah menafsirkan "bilangan bulat positif" untuk disertakan
0
, meskipun0
tidak positif. Saya menyertakan catatan jika Anda ingin melarang0
.Berdasarkan Parsing
Jika Anda menginginkannya menjadi string integer desimal yang dinormalisasi pada rentang nilai yang wajar, Anda dapat melakukan ini:
atau jika Anda ingin membolehkan spasi putih dan memimpin nol:
Testbed langsung (tanpa menangani angka nol atau spasi kosong):
Tampilkan cuplikan kode
Testbed langsung ( dengan penanganan untuk memimpin nol dan spasi putih):
Tampilkan cuplikan kode
Jika Anda ingin melarang
0
, ubah saja>= 0
ke> 0
. (Atau, dalam versi yang memungkinkan angka nol di depan, hapus angka|| "0"
direplace
telepon.)Cara kerjanya:
Dalam versi yang memungkinkan spasi dan nol terkemuka:
str = str.trim();
menghapus whitepace terkemuka dan tertinggal.if (!str)
menangkap string kosong dan kembali, tidak ada gunanya melakukan sisa pekerjaan.str = str.replace(/^0+/, "") || "0";
menghapus semua 0 terkemuka dari string - tetapi jika itu menghasilkan string kosong, mengembalikan satu 0.Number(str)
: Konversistr
ke angka; jumlahnya mungkin memiliki porsi fraksional, atau mungkinNaN
.Math.floor
: Pangkas angkanya (memotong bagian pecahan).String(...)
: Mengubah hasil kembali menjadi string desimal normal. Untuk jumlah yang sangat besar, ini akan masuk ke notasi ilmiah, yang mungkin mematahkan pendekatan ini. (Saya tidak tahu di mana perpecahan itu, detailnya ada dalam spesifikasi , tetapi untuk bilangan bulat, saya yakin itu pada titik Anda telah melampaui 21 digit [saat itu jumlahnya menjadi sangat tidak tepat, seperti IEEE-754 angka presisi ganda hanya memiliki presisi 15 digit ..)... === str
: Membandingkannya dengan string asli.n >= 0
: Periksa apakah itu positif.Perhatikan bahwa ini gagal untuk input
"+1"
, input apa pun dalam notasi ilmiah yang tidak berubah menjadi notasi ilmiah yang sama di atasString(...)
panggung, dan untuk nilai apa pun yang digunakan oleh nomor jenis JavaScript (IEEE-754 floating point biner presisi ganda) tidak dapat secara akurat menunjukkan parses mana yang lebih dekat ke nilai yang berbeda dari yang diberikan (yang mencakup banyak bilangan bulat lebih dari 9.007.199.254.740.992; misalnya,1234567890123456789
akan gagal). Yang pertama adalah perbaikan yang mudah, dua yang terakhir tidak begitu banyak.Ekspresi Reguler
Pendekatan lain adalah untuk menguji karakter string melalui ekspresi reguler, jika tujuan Anda hanya mengizinkan (katakanlah) sebuah opsi
+
diikuti oleh salah satu0
atau string dalam format desimal normal:Testbed langsung:
Tampilkan cuplikan kode
Cara kerjanya:
^
: Cocokkan mulai dari string\+?
: Izinkan satu, opsional+
(hapus ini jika Anda tidak mau)(?:...|...)
: Izinkan salah satu dari dua opsi ini (tanpa membuat grup tangkap):(0|...)
: Izinkan0
sendiri ...(...|[1-9]\d*)
: ... atau angka yang dimulai dengan sesuatu selain0
dan diikuti oleh sejumlah angka desimal.$
: Cocokkan ujung string.Jika Anda ingin melarang
0
(karena itu tidak positif), ekspresi reguler menjadi adil/^\+?[1-9]\d*$/
(misalnya, kita dapat kehilangan pergantian yang perlu kami izinkan0
).Jika Anda ingin membolehkan angka nol di depan (0123, 00524), maka ganti saja alternasinya
(?:0|[1-9]\d*)
dengan\d+
Jika Anda ingin membolehkan spasi putih, tambahkan
\s*
setelah^
dan\s*
sebelum$
.Catatan untuk ketika Anda mengonversikannya menjadi angka: Pada mesin modern mungkin akan baik untuk digunakan
+str
atauNumber(str)
melakukannya, tetapi yang lebih tua mungkin memperpanjangnya dengan cara yang tidak standar (tetapi sebelumnya diizinkan) yang mengatakan nol di depan berarti oktal (basis 8), mis. "010" => 8. Setelah Anda memvalidasi angka, Anda dapat menggunakan dengan amanparseInt(str, 10)
untuk memastikan bahwa itu diuraikan sebagai desimal (basis 10).parseInt
akan mengabaikan sampah di akhir string, tetapi kami telah memastikan tidak ada dengan regex.sumber
Number(' ')
danNumber('')
kembali0
sementara harusNaN
sebaliknya.parseInt
kembali2
./\D/.test('2a')
benar (karena ada non-digit). Jadi mungkinif (!/\D/.test(str) && !isNan((num = parseInt(str, 10))) { /* Valid number in num */}
... Tepat di atas kepala saya ...Solusi 1
Jika kami menganggap integer JavaScript sebagai nilai maksimum
4294967295
(yaituMath.pow(2,32)-1
), maka solusi singkat berikut ini akan berfungsi dengan baik:DESKRIPSI:
123.45 >>> 0 === 123
-1 >>> 0 === 4294967295
MAX_INT
1e10 >>> 0 === 1410065408
1e7 >>> 0 === 10000000
parseFloat
melakukan parsing nomor string yang benar (pengaturanNaN
untuk string non numerik)UJI:
DEMO: http://jsfiddle.net/5UCy4/37/
Solusi 2
Cara lain baik untuk semua nilai numerik yang valid hingga
Number.MAX_VALUE
, yaitu sekitar1.7976931348623157e+308
:DESKRIPSI:
!isNaN(parseFloat(n))
digunakan untuk menyaring murni nilai string, misalnya""
," "
,"string"
;0 <= ~~n
menyaring negatif dan nilai-nilai non-integer besar, misalnya"-40.1"
,"129000098131766699"
;(!isNaN(parseFloat(n)) && 0 <= ~~n)
kembalitrue
jika nilainya numerik dan positif ;0 === n % (...)
memeriksa apakah nilainya tidak mengambang - di sini(...)
(lihat 3) dievaluasi seperti0
dalam kasusfalse
, dan seperti1
dalam kasustrue
.UJI:
DEMO: http://jsfiddle.net/5UCy4/14/
Versi sebelumnya:
DEMO: http://jsfiddle.net/5UCy4/2/
sumber
~~val
, memotong bagian fraksional. Ini sedikit lebih cepat karena melakukan satu operasi bitwise bukannya dua.(!isNaN(parseFloat(n)) && n % 1 === 0 && 0 <= ~~n)
true, false, 0xFF
, dan nilai-nilai lainnya berhasilisPositiveInteger
tanpa terdeteksi.Sepertinya ekspresi reguler adalah caranya:
sumber
0
tempat yang biasanya tidak Anda harapkan, tetapi sebagian besar, tampaknya baik-baik saja.Solusi modern yang bekerja di node dan di lebih dari 90% dari semua browser (kecuali IE dan Opera Mini) adalah dengan menggunakan Number.isInteger diikuti oleh pemeriksaan positif sederhana.
Ini diselesaikan dalam ECMAScript 2015 .
Polyfil adalah:
Jika Anda perlu mendukung input yang mungkin dalam bentuk string atau angka maka Anda dapat menggunakan fungsi ini Saya menulis sebuah test suite besar setelah semua jawaban yang ada (2/1/2018) gagal pada beberapa bentuk input.
sumber
Ini hampir merupakan pertanyaan rangkap untuk pertanyaan ini:
Validasi angka desimal dalam JavaScript - IsNumeric ()
Jawabannya adalah:
jadi, bilangan bulat positif adalah:
sumber
tidak akan bekerja jika Anda memberikan string seperti '0001'
sumber
Fungsi saya memeriksa apakah angka + ve dan bisa memiliki nilai desimal juga.
sumber
Hanya untuk membangun jawaban VisioN di atas, jika Anda menggunakan plugin validasi jQuery Anda dapat menggunakan ini:
Kemudian Anda dapat menggunakan dalam aturan normal Anda mengatur atau menambahkannya secara dinamis dengan cara ini:
sumber
Sederhana
Anda juga dapat menambah Nomor dan menetapkan fungsinya melalui prototipe.
sumber
Jika Anda menggunakan formulir HTML5, Anda bisa menggunakan atribut
min="0"
untuk elemen formulir<input type="number" />
. Ini didukung oleh semua browser utama. Itu tidak melibatkan Javascript untuk tugas-tugas sederhana seperti itu, tetapi terintegrasi dalam standar html baru. Itu didokumentasikan di https://www.w3schools.com/tags/att_input_min.aspsumber
(~~a == a)
dimanaa
senarnya.sumber
~~"-1" == "-1"
akan kembalitrue
. Dan OP hanya meminta bilangan bulat positif.ES6:
sumber