Làm cách nào để kiểm tra xem giá trị có phải là số không?


82

Tôi chỉ muốn kiểm tra xem giá trị trả về từ trường văn bản biểu mẫu có phải là số hay không, tức là: 12, 12,5 hoặc 12,75. Có cách nào đơn giản để kiểm tra điều này không, đặc biệt nếu giá trị được kéo dưới dạng a param?


ừm, điều duy nhất là mã hoạt động cho is_a_number? hoạt động với ngoại lệ duy nhất là các số .02 hoặc .3 ....
user211662

7
Tôi thích giải pháp này hơn: stackoverflow.com/questions/5661466/… Tôi không biết tại sao rất nhiều người nghĩ rằng regexp sẽ tốt hơn cho điều đó.
2called-hỗn loạn

Câu trả lời:


26

Chỉ cần regexp nó, nó tầm thường và không đáng để suy nghĩ về điều đó:

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

(Đã sửa theo nhận xét của Justin)


5
Trong ruby, ^ và $ biểu thị đầu / cuối của một dòng, không phải của một chuỗi. Điều này làm cho điều này không hiệu quả để sử dụng làm phương tiện khử trùng đầu vào (xem Guide.rubyonrails.org/security.html#regular-expressions ). Một cách tiếp cận tốt hơn sẽ là: v.to_s =~ /\A[-+]?\d*\.?\d+\z/.
Justin

204

Bạn có thể dùng

12.is_a? Numeric

( Numericsẽ hoạt động với số nguyên và số thực.)

Nếu nó đến dưới dạng một chuỗi có thể chứa đại diện của một số hợp lệ, bạn có thể sử dụng

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

và sau đó '12'.valid_float?sẽ trả về true nếu bạn có thể chuyển đổi chuỗi thành một float hợp lệ (ví dụ: với to_f).


Xin lỗi, đây là Ruby on Rails ... Về cơ bản, tôi chỉ muốn có thể đánh giá bất kỳ đầu vào nào từ người dùng cho dù đó là 0,03 0,3, 2,2 Hai thứ sau hoạt động, nhưng tôi cần phải có được đầu vào đầu tiên hoạt động: S
user211662

10
Fixnumdường như không hoạt động với phao. Tuy nhiên, Numerichoạt động tốt. Vì vậy 1.234.is_a? Fixnum == false, nhưng 1.234.is_a? Numeric == true.
KurtPreston

Điều này không hoạt động với phao. Nên sử dụng 1.1.is_a? NumericXem stackoverflow.com/a/17668654/76486
Brian Armstrong,

1
Không làm việc cho tôi :(pry(main)> '12'.is_a? Numeric => false
Salil

@Salil rõ ràng là sẽ không hiệu quả với bạn, '12'là một Chuỗi. Trong trường hợp đó, hãy kiểm tra chuỗi bằng Regex hoặc bất kỳ giải pháp khả thi nào khác.
edmundo096

27

Tôi thường chỉ sử dụng Integer và Float những ngày này.

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

Chỉ cần chuyển đổi chuỗi hai lần:

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

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

Làm việc không đến nỗi tệ với số nguyên, nhưng có rất nhiều cách để thất bại nếu bạn muốn làm theo lời khuyên này với phao nổi (đó là những gì các câu hỏi yêu cầu về): "7" == "7".to_f.to_s #=> false( "7" vs "7.0")
David Stosik

Bạn có thể làmnum == num.to_i.to_s || num == num.to_f.to_s
mannykary

bạn cũng có thể định dạng cả hai chuỗi bằng cách sử dụng toán tử "%" để đảm bảo rằng cả hai đều kết thúc trong cùng một chuỗi
Jaacko Torus

5

Tôi sẽ đề nghị cái này

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

6
"1.1" .is_a? Numeric => false
Waclock

Bạn sẽ giải quyết vấn đề chuyển đổi chuỗi như thế nào? OP cho biết nó từ một trường văn bản.
schlingel

-5

Giá trị chuỗi luôn chuyển đổi thành 0 với .to_i

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

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

Còn về các trường hợp cạnh? Nếu con số là 0 hoặc âm tính, xét nghiệm của bạn sẽ cho kết quả âm tính giả.
tsikov

Thậm chí tệ hơn '1AB2'.to_i sẽ trở về 1 cái gì đó rõ ràng không phải là một Integer ...
Thomas Bindzus
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.