Bir değerin sayı olup olmadığını nasıl kontrol edebilirim?


82

Bir form metin alanından döndürülen değerin bir sayı olup olmadığını kontrol etmek istiyorum, yani: 12, 12.5 veya 12.75. Bunu kontrol etmenin basit bir yolu var mı, özellikle de değer a olarak alındığında param?


um, tek şey kodun is_a_number için çalıştığıdır? .02 veya .3 sayıları hariç tek istisna çalışır ....
user211662

7
Bu çözümü daha çok tercih ederim: stackoverflow.com/questions/5661466/… Neden bu kadar çok insanın bir regexp'in bunun için daha iyi olacağını düşündüğünü bilmiyorum.
2called-chaos

Yanıtlar:


26

Sadece yeniden ifade edin, önemsizdir ve bunun ötesinde düşünmeye değmez:

v =~ /\A[-+]?[0-9]*\.?[0-9]+\Z/

(Justin'in yorumuna göre düzeltildi)


5
Ruby'de, ^ ve $ bir dizenin değil, bir satırın başlangıcını / sonunu belirtir. Bu, girdileri sterilize etmenin bir yolu olarak kullanılmasını etkisiz hale getirir (bkz. Guides.rubyonrails.org/security.html#regular-expressions ). Daha iyi bir yaklaşım olacaktır: v.to_s =~ /\A[-+]?\d*\.?\d+\z/.
Justin

207

Kullanabilirsiniz

12.is_a? Numeric

( Numerictamsayılar ve kayan sayılar için çalışacaktır.)

Geçerli bir sayının temsilini içerebilecek bir dize olarak gelirse, şunu kullanabilirsiniz:

class String
  def valid_float?
    true if Float self rescue false
  end
end

ve '12'.valid_float?dizeyi geçerli bir şamandıraya dönüştürebilirseniz (örn. ile to_f) true döndürür .


Üzgünüm, bu Ruby on Rails ... Temel olarak, kullanıcıdan gelen herhangi bir girdiyi, .03 0.3, 2.2 olsun, değerlendirebilmek istiyorum. Son iki iş, ama ilk girdiyi çalıştırmam gerekiyor: S
user211662

10
Fixnumşamandıralarla çalışmıyor gibi görünüyor. Ancak, iyi Numericçalışıyor. Yani 1.234.is_a? Fixnum == false, ama 1.234.is_a? Numeric == true.
KurtPreston

Bu şamandıralarla çalışmaz. Kullanılmalıdır 1.1.is_a? NumericBkz. Stackoverflow.com/a/17668654/76486
Brian Armstrong

1
Benim için çalışmıyor :(pry(main)> '12'.is_a? Numeric => false
Salil

@ Salil belli ki sizin için işe yaramayacak '12', bir String. Bu durumda dizeyi Regex veya diğer olası çözümlerle kontrol edin.
edmundo096

27

Bu günlerde genellikle sadece Tamsayı ve Float kullanıyorum.

1.9.2p320 :001 > foo = "343"
 => "343"
1.9.2p320 :003 > goo = "fg5"
 => "fg5"

1.9.2p320 :002 > Integer(foo) rescue nil
 => 343
1.9.2p320 :004 > Integer(goo) rescue nil
 => nil

1.9.2p320 :005 > Float(foo) rescue nil
 => 343.0
1.9.2p320 :006 > Float(goo) rescue nil
 => nil


7

Sadece dizeyi iki kez dönüştürün:

num = '12'
num == num.to_i.to_s 
#=> true 

num = '3re'
num == num.to_i.to_s 
#=> false

Tamsayılarla o kadar da kötü çalışmıyor, ancak bu tavsiyeyi kayan sayılarla takip etmek istiyorsanız başarısız olmanın pek çok yolu var (sorunun sorduğu soru budur): "7" == "7".to_f.to_s #=> false("7" ve "7.0")
David Stosik

Yapabilirsinnum == num.to_i.to_s || num == num.to_f.to_s
mannykary

Her ikisinin de aynı dizeyle bitmesini garanti etmek için her iki dizeyi de "%" operatörünü kullanarak biçimlendirebilirsiniz
Jaacko Torus

5

Bunu öneririm

def is_number?
  self.to_f == self
end

> 15.is_number?
=> true
> 15.0.is_number?
=> true
> 'Not a number'.is_number?
=> false
> (0/0.0).is_number?
=> false

4
irb(main):005:0> 1.1.is_a? Numeric
=> true
irb(main):006:0> 1.is_a? Numeric
=> true
irb(main):007:0> 'asd'.is_a? Numeric
=> false

7
"1.1" .is_a? Sayısal => yanlış
Waclock

Dize dönüştürme problemini nasıl çözersiniz? OP, bir metin alanından olduğunu belirtir.
schlingel

-5

Dize değerleri her zaman .to_i ile 0'a dönüştürülür

[14] pry(main)> 'Apple'.to_i > 0
=> false

[15] pry(main)> '101'.to_i > 0
=> true

Peki ya uç durumlar? Sayı 0 veya negatifse, testiniz yanlış bir negatif verecektir.
tsikov

Daha da kötüsü '1AB2'.to_i, açıkça Tamsayı olmayan bir şey için 1 değerini döndürür ...
Thomas Bindzus
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.