2010-01-19 20 views
64

Quiero simplemente verificar si un valor devuelto de un campo de texto de formulario es un número, es decir, 12, 12.5 o 12.75. ¿Hay alguna manera simple de verificar esto, especialmente si el valor se extrae como param?¿Cómo puedo verificar si un valor es un número?

+0

um, lo único es que el código funciona para is_a_number? funciona con la única excepción de .02 o .3 números .... – user211662

+5

Yo prefiero esta solución: http://stackoverflow.com/questions/5661466/test-if-string-is-a-number-in- ruby-on-rails/5661695 No sé por qué tanta gente piensa que una expresión regular sería mejor para eso. –

Respuesta

20

Sólo expreg él, es trivial, y no vale la pena pensar más allá de eso:

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

(Fijo según el comentario de Justin)

+5

En ruby,^y $ denotan el comienzo/final de una línea, no de una cadena. Esto hace que esto no sea efectivo para usar como medio de desinfección de insumos (ver http://guides.rubyonrails.org/security.html#regular-expressions). Un mejor enfoque sería: 'v.to_s = ~/\ A [- +]? \ D * \.? \ D + \ z /'. – Justin

+10

que no es trivial, ¡piensa en alguien que no tenga tanta experiencia! –

152

Puede utilizar

12.is_a? Numeric 

(Numeric funcionará para los enteros y los flotadores.)

Si llega como una cadena que puede contener una representación de un número válido, podría utilizar

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

y luego '12'.valid_float? devolverá verdadero si puede convertir la cadena en un flotante válido (por ejemplo, con to_f).

+4

basado en el título, pensé que esto era para ruby ​​(no rieles) ... – Peter

+0

Lo siento, esto es Ruby on Rails ... Básicamente, solo quiero poder evaluar cualquier entrada del usuario, ya sea. 03 0.3, 2.2 Los dos últimos funcionan, pero necesito que la primera entrada funcione: S – user211662

+10

'' 'Fixnum''' no parece funcionar con flotadores. Sin embargo, '' 'Numeric''' funciona bien. Entonces '' '1.234.is_a? Fixnum == falso''', pero '' '1.234.is_a? Numérico == verdadero'''. – KurtPreston

5

Yo sugeriría éste

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

No funciona para Float :: INFINITY –

20

Suelo usar Integer y Float en estos días.

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? Numérico => falso – Waclock

+0

¿Cómo abordaría el problema de conversión de cadenas? OP dice que es de un campo de texto. – schlingel

-3

valores de cadena siempre se convierten a 0 con .to_i

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

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

¿Qué hay de las cajas de borde? Si el número es 0 o negativo, su prueba dará un falso negativo. – tsikov

+0

Aún peor '1AB2'.to_i devolvería 1 para algo que claramente no es un Entero ... –

5

Sólo convertir la cadena en dos ocasiones:

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

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

No funciona tan mal con enteros, pero hay tantas maneras de fallar si desea seguir este consejo con flotadores (que es de qué se trata la pregunta): '" 7 "==" 7 ".to_f.to_s # => false' (" 7 "frente a" 7.0 ") –

Cuestiones relacionadas