2010-01-19 19 views
64

Voglio semplicemente verificare se un valore restituito da un campo di testo del modulo è un numero, ad es. 12, 12.5 o 12.75. C'è un modo semplice per controllare questo, soprattutto se il valore viene tirato come param?Come posso verificare se un valore è un numero?

+0

um, l'unica cosa è che il codice funziona per is_a_number? funziona con l'unica eccezione di .02, o .3 numeri .... – user211662

+5

Preferisco di gran lunga questa soluzione: http://stackoverflow.com/questions/5661466/test-if-string-is-a-number-in- ruby-on-rails/5661695 Non so perché così tante persone pensano che una regexp sarebbe meglio per questo. –

risposta

20

Proprio regexp esso, è banale, e non la pena di pensare al di là:

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

(fisso come da commento di Justin)

+5

In ruby,^e $ indicano l'inizio/la fine di una riga, non di una stringa. Ciò rende questo inefficace usare come mezzo per disinfettare gli input (vedi http://guides.rubyonrails.org/security.html#regular-expressions). Un approccio migliore sarebbe: 'v.to_s = ~/\ A [- +]? \ D * \.? \ D + \ z /'. – Justin

+10

che non è banale, pensa a qualcuno che non è così esperto! –

152

È possibile utilizzare

12.is_a? Numeric 

(Numeric funzionerà per gli interi e carri allegorici.)

Se arriva come una stringa che potrebbe contenere una rappresentazione di un numero valido, è possibile utilizzare

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

e quindi '12'.valid_float? restituirà true se è possibile convertire la stringa in un valore valido (ad esempio con to_f).

+4

basato sul titolo, ho pensato che fosse per ruby ​​(non rotaie) ... – Peter

+0

Mi spiace, questo è Ruby on Rails ... Fondamentalmente, voglio solo essere in grado di valutare qualsiasi input da parte dell'utente sia. 03 0.3, 2.2 Gli ultimi due funzionano, ma ho bisogno di ottenere il primo input funzionante: S – user211662

+10

'' 'Fixnum''' non sembra funzionare con i float. Tuttavia, '' 'Numeric''' funziona bene. Quindi '' '1.234.is_a? Fixnum == false''', ma '' '1.234.is_a? Numerico == true'''. – KurtPreston

5

vorrei suggerire questo

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

Non funziona per Float :: INFINITY –

20

Di solito uso solo Integer e Float in questi giorni.

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? Numerico => false – Waclock

+0

Come affrontare il problema di conversione String? OP afferma che proviene da un campo di testo. – schlingel

-3

valori stringa convertono sempre a 0 con .to_i

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

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

E i casi limite? Se il numero è 0 o negativo, il test darà un falso negativo. – tsikov

+0

Ancora peggio '1AB2'.to_i restituirebbe 1 per qualcosa che chiaramente non è un numero intero ... –

5

solo convertire stringa due volte:

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

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

Non funziona così male con i numeri interi, ma ci sono tanti modi per fallire se si vuole seguire questo consiglio con i float (che è di cosa si pone la domanda): '" 7 "==" 7 ".to_f.to_s # => false' (" 7 "vs" 7.0 ") –

Problemi correlati