Apa cara terbersih dan paling efektif untuk memvalidasi angka desimal dalam JavaScript?
Poin bonus untuk:
- Kejelasan. Solusi harus bersih dan sederhana.
- Lintas-platform.
Kasus uji:
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
javascript
validation
numbers
Michael Haren
sumber
sumber
jQuery.isNumeric
fungsi utilitas: api.jquery.com/jQuery.isNumericjQuery.isNumeric
akan gagal dalam test case ketujuh OP (IsNumeric('0x89f') => *false*
). Saya tidak yakin apakah saya setuju dengan test case ini.Jawaban:
@Jawab Joel cukup dekat, tetapi akan gagal dalam kasus berikut:
Beberapa waktu yang lalu saya harus mengimplementasikan suatu
IsNumeric
fungsi, untuk mengetahui apakah suatu variabel berisi nilai numerik, terlepas dari jenisnya , itu bisa berupaString
nilai numerik (saya harus mempertimbangkan juga notasi eksponensial, dll.), SebuahNumber
objek, hampir semua hal bisa diteruskan ke fungsi itu, saya tidak bisa membuat asumsi tipe apa pun, mengurus tipe paksaan (mis.+true == 1;
tetapitrue
tidak boleh dianggap sebagai"numeric"
).Saya pikir layak berbagi set +30 unit test yang dibuat untuk banyak implementasi fungsi, dan juga berbagi yang melewati semua tes saya:
PS Isnan & isFinite memiliki perilaku membingungkan karena konversi dipaksa untuk nomor. Dalam ES6, Number.isNaN & Number.isFinite akan memperbaiki masalah ini. Ingatlah hal itu saat menggunakannya.
Pembaruan : Begini caranya jQuery melakukannya sekarang (2.2-stable) :
Pembaruan : Angular 4.3 :
sumber
2e308 > Number.MAX_VALUE
sejak2e308 == Infinity
. Jika Anda menginginkan fungsi yang mengembalikantrue
juga untuk nilai infinity positif dan negatif, periksa fungsi No. 2 di dalam suite pengujian . Bersulang.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:Begini cara kerjanya:
The
(input - 0)
ekspresi memaksa JavaScript untuk melakukan jenis paksaan nilai masukan Anda; pertama-tama harus ditafsirkan sebagai angka untuk operasi pengurangan. Jika konversi ke nomor gagal, ekspresi akan menghasilkanNaN
. Ini numerik hasil ini kemudian dibandingkan dengan nilai asli Anda lulus dalam. Sejak sisi kiri sekarang numerik, jenis paksaan lagi digunakan. 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 mengatakanNaN
tidak pernah sama denganNaN
, 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 bungkus saja fungsi Anda sendiriisNaN()
yang juga dapat melakukan pemeriksaan tambahan.Singkatnya, jika Anda ingin tahu apakah suatu nilai dapat dikonversi ke angka, sebenarnya cobalah untuk mengubahnya menjadi angka.
Saya kembali dan melakukan penelitian untuk mengapa string spasi tidak memiliki output yang diharapkan, dan saya pikir saya mengerti sekarang: string kosong dipaksa untuk
0
bukanNaN
. Cukup memangkas string sebelum pemeriksaan panjang akan menangani kasus ini.Menjalankan tes 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 itu 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 ().
sumber
IsNumeric(' ')
,IsNumeric('\n\t')
, dll semua kembalitrue
Number
literalIsNumeric(5) == false;
memeriksa set unit test yang saya posting, fungsi ini adalah nomor16
pada test suite. stackoverflow.com/questions/18082/…Cara ini tampaknya bekerja dengan baik:
Dalam satu baris:
Dan untuk mengujinya:
Saya meminjam regex itu dari http://www.codetoad.com/javascript/isnumeric.asp . Penjelasan:
sumber
Yahoo! UI menggunakan ini:
sumber
new Number(1)
.Ini berfungsi untuk nomor tipe 0x23 juga.
sumber
IsNumeric('')
,IsNumeric(' ')
,IsNumeric(true)
,IsNumeric(false)
,IsNumeric(null)
Kembalitrue
bukanfalse
.Jawaban yang diterima gagal dalam tes Anda # 7 dan saya rasa itu karena Anda berubah pikiran. Jadi ini adalah jawaban atas 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 posting tentang stackoverflow yang telah diterima secara luas sebagai jawabannya, rutin umum yang sama yang digunakan oleh perpustakaan yang disebutkan sebelumnya.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 itu array maka itu bukan numerik.
Untuk mengatasi masalah ini, saya menambahkan tanda centang ke array diskon dari logika
Tentu saja, Anda juga bisa menggunakan
Array.isArray
, jquery$.isArray
atau prototipeObject.isArray
alih-alihObject.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 numerik yang valid.
Saya kemudian memodifikasi logika untuk memperhitungkan ini.
Jika Anda khawatir tentang pembuatan regex setiap kali fungsi dipanggil maka Anda bisa menulis ulang dalam penutupan, sesuatu seperti ini
Saya kemudian mengambil CMS +30 test case dan mengkloning pengujian pada jsfiddle menambahkan test case ekstra saya dan solusi yang saya jelaskan di atas.
Itu mungkin tidak menggantikan jawaban yang diterima secara luas / digunakan tetapi jika ini lebih dari apa yang Anda harapkan sebagai hasil dari fungsi isnumerik Anda maka 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 pemikiran ini saya akan menambah kriteria.
Saya ingin fungsi isNumeric saya hanya mempertimbangkan Bilangan atau String
Dengan pemikiran ini, akan lebih baik untuk digunakan
Uji solusinya
sumber
IsNumeric('99,999') => false
Ya, built-in
isNaN(object)
akan jauh lebih cepat daripada parsing regex mana pun, karena itu built-in dan dikompilasi, daripada ditafsirkan dengan cepat.Meskipun hasilnya agak berbeda dengan yang Anda cari ( coba ):
sumber
Gunakan fungsinya
isNaN
. Saya percaya jika Anda menguji untuk!isNaN(yourstringhere)
itu berfungsi dengan baik untuk semua situasi ini.sumber
Sejak jQuery 1.7, Anda dapat menggunakan
jQuery.isNumeric()
:Perhatikan bahwa tidak seperti apa yang Anda katakan,
0x89f
angka yang valid (hexa)sumber
Itu dapat dilakukan tanpa RegExp sebagai
sumber
Saya menyadari pertanyaan asli tidak menyebutkan jQuery, tetapi jika Anda menggunakan jQuery, Anda dapat melakukannya:
Sederhana.
https://api.jquery.com/jQuery.isNumeric/ (per jQuery 1.7)
sumber
tidak bekerja untuk saya. Ketika saya dimasukkan ke dalam peringatan dan diuji,
input.length
adalahundefined
. Saya pikir tidak ada properti untuk memeriksa panjang bilangan bulat. Jadi yang saya lakukan adalahItu bekerja dengan baik.
sumber
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, mereka adalah operator terpisah):Saya memerlukan 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 nomor JavaScript.
Nomor yang valid meliputi:
Angka yang tidak valid adalah
sumber
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 memeriksaNaN
adalah dengan memeriksa nilai numerik yang tidak sama dengan diri mereka sendiriNaN != NaN
,! Jadi sebenarnya ada 3 tes yang ingin Anda lakukan ...IsComparableNumber saya cukup dekat dengan jawaban elegan lain , tetapi menangani hex dan representasi string angka lainnya.
sumber
Bagi saya, ini adalah cara terbaik:
sumber
Saya ingin menambahkan yang berikut ini:
Bilangan hex positif dimulai dengan
0x
dan bilangan hex negatif dimulai dengan-0x
. Bilangan oktri positif dimulai dengan0
dan angka ok negatif dimulai dengan-0
. Yang ini mengambil sebagian besar dari apa yang telah disebutkan dalam pertimbangan, tetapi termasuk angka hex dan oktal, ilmiah negatif, Infinity dan telah menghilangkan ilmiah desimal (4e3.2
tidak valid).sumber
Saya pikir fungsi parseFloat dapat melakukan semua pekerjaan di sini. Fungsi di bawah ini lulus semua tes pada halaman ini termasuk
isNumeric(Infinity) == true
:sumber
IsNumeric([3]) == true;
IsNumeric([]) == false;
IsNumeric([3, 4]) == false;
Tapi saya bayangkan itu masalah selera!Beberapa tes untuk ditambahkan:
Saya datang dengan ini:
Solusinya meliputi:
sumber
Nilai integer dapat diverifikasi oleh:
Cara ini lebih mudah dan lebih cepat! Semua tes diperiksa!
sumber
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:
Kelemahan dari versi jQuery adalah bahwa jika Anda melewatkan string dengan memimpin numeric dan trailing huruf seperti
"123abc"
yangparseFloat | parseInt
akan mengekstrak fraksi numerik dan kembali 123, NAMUN, penjaga keduaisFinite
akan gagal pula. Dengan+
operator unary itu akan mati pada penjaga pertama sejak + melempar NaN untuk hibrida tersebut :) Sedikit kinerja namun saya pikir keuntungan semantik yang solid.sumber
Solusi saya,
Tampaknya berfungsi dalam setiap situasi, tetapi saya mungkin salah.
sumber
?
untuk{0,1}
dan\d
untuk[0-9]
. Juga+
dan kemudian membungkusnya dengan(?:){0,1}
, Anda mungkin juga menggunakan*
dan melupakan kelompok (bukan) yang menangkap.Saya menggunakan solusi yang lebih sederhana:
sumber
Ini seharusnya bekerja. Beberapa fungsi yang disediakan di sini cacat, juga harus lebih cepat daripada fungsi lain di sini.
Dijelaskan:
Buat salinannya sendiri, lalu ubah nomornya menjadi float, lalu bandingkan dengan nomor aslinya, jika masih berupa angka, (apakah bilangan bulat atau float), dan cocok dengan angka aslinya, itu berarti, itu memang angka.
Ini bekerja dengan string numerik serta angka polos. Tidak berfungsi dengan angka heksadesimal.
Peringatan: gunakan dengan risiko Anda sendiri, tanpa jaminan.
sumber
Tidak ada jawaban yang dikembalikan
false
untuk string kosong, perbaikan untuk itu ...sumber
Untuk memeriksa apakah variabel berisi angka yang valid dan bukan hanya String yang terlihat seperti angka,
Number.isFinite(value)
dapat digunakan.Ini adalah bagian dari bahasa sejak ES2015
Contoh:
sumber
Number.isFinite('0') -> false
Jika n adalah numerik
Number(n)
akan mengembalikan nilai numerik dantoString()
akan mengubahnya kembali menjadi string. Tetapi jika n bukan numerikNumber(n)
akan kembaliNaN
sehingga tidak akan cocok dengan aslinyan
sumber
Saya menyadari ini telah dijawab berkali-kali, tetapi berikut ini adalah kandidat yang layak yang dapat berguna dalam beberapa skenario.
Perlu dicatat bahwa diasumsikan bahwa '.42' BUKAN angka, dan '4.' BUKAN angka, jadi ini harus diperhitungkan.
The
isDecimal
melewati tes berikut:Idenya di sini adalah bahwa setiap bilangan 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-fungsi ini berguna bagi Anda tergantung pada use case. Salah satu fitur adalah bahwa string yang berbeda mewakili angka yang berbeda (jika keduanya lulus
isNumber()
tes).Ini relevan misalnya untuk angka sebagai nama properti objek.
sumber
fungsi validasi perpustakaan knockoutJs Inbuild
Dengan memperpanjangnya, bidang tersebut dapat divalidasi
1) angka
self.number = ko.observable(numberValue)
.extend ({number: true}) ;Kasus cobaan
2) digit
self.number = ko.observable(numberValue)
.extend ({digit: true}) ;Kasus cobaan
3) min dan maks
self.number = ko.observable(numberValue)
.extend ({min: 5}). extended ({max: 10}) ;Bidang ini hanya menerima nilai antara 5 dan 10
Kasus cobaan
sumber
Jika Anda perlu memvalidasi set desimal khusus, Anda dapat menggunakan javascript sederhana ini:
http://codesheet.org/codesheet/x1kI7hAD
Javascript:
sumber
isNumeric=(el)=>{return Boolean(parseFloat(el)) && isFinite(el)}
Tidak ada yang sangat berbeda tetapi kita dapat menggunakan konstruktor Boolean
sumber