2010-01-19 71 views
64

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

+0

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

+5

Tôi rất thích giải pháp này: http://stackoverflow.com/questions/5661466/test-if-string-is-a-number-in- ruby-on-rails/5661695 Tôi không biết tại sao rất nhiều người nghĩ rằng một regexp sẽ tốt hơn cho điều đó. –

Trả lời

20

Chỉ cần regexp nó, nó tầm thường, và không đáng suy nghĩ về xa hơn rằng:

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

(Cố định theo bình luận 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 như một phương tiện vệ sinh đầu vào (xem http://guides.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

+10

đó không phải là tầm thường, suy nghĩ của một người không có kinh nghiệm! –

152

Bạn có thể sử dụng

12.is_a? Numeric 

(Numeric sẽ làm việc cho số nguyên và nổi.)

Nếu nó đến như là một chuỗi có thể chứa một đạ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 phao hợp lệ (ví dụ: to_f).

+4

dựa trên tiêu đề, tôi nghĩ rằng điều này là cho ruby ​​(không đường ray) ... – Peter

+0

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à. 03 0,3, 2,2 Sau hai công việc, nhưng tôi cần phải có được đầu vào đầu tiên làm việc: S – user211662

+10

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

5

tôi sẽ đề nghị 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 
+0

Không hoạt động cho Float :: INFINITY –

20

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 
6
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 
+5

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

+0

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

-3

giá trị Chuỗi luôn chuyển đổi sang 0 với .to_i

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

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

Còn các trường hợp cạnh thì sao? Nếu số đó là 0 hoặc âm thì phép thử của bạn sẽ cho âm sai. – tsikov

+0

Thậm chí tệ hơn '1AB2'.to_i sẽ trả về 1 cho cái gì đó rõ ràng không phải là một số nguyên ... –

5

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 
+0

Hoạt động không quá 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 (đó là câu hỏi yêu cầu): '" 7 "==" 7 ".to_f.to_s # => false' (" 7 "so với" 7.0 ") –

Các vấn đề liên quan