¿Cómo puedo comprobar si un valor es un número?


82

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. ¿Existe una forma sencilla de comprobar esto, especialmente si el valor se extrae como param?


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

7
Prefiero esta solución: stackoverflow.com/questions/5661466/… No sé por qué tanta gente piensa que una expresión regular sería mejor para eso.
2called-caos

Respuestas:


26

Simplemente regexp, es trivial, y no vale la pena pensar más allá de eso:

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

(Corregido 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 sea ineficaz para usarlo como un medio para desinfectar las entradas (consulte guides.rubyonrails.org/security.html#regular-expressions ). Un mejor enfoque sería: v.to_s =~ /\A[-+]?\d*\.?\d+\z/.
Justin

204

Puedes usar

12.is_a? Numeric

( Numericfuncionará para enteros y flotantes).

Si llega como una cadena que puede contener una representación de un número válido, puede usar

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).


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 funcione la primera entrada: S
user211662

10
Fixnumno parece funcionar con flotadores. Sin embargo, Numericfunciona bien. Entonces 1.234.is_a? Fixnum == false, pero 1.234.is_a? Numeric == true.
KurtPreston

Esto no funciona con flotadores. Debe usar 1.1.is_a? NumericVer stackoverflow.com/a/17668654/76486
Brian Armstrong

1
No funciona para mí :(pry(main)> '12'.is_a? Numeric => false
Salil

@Salil obviamente eso no funcionará para ti, '12'es un String. En ese caso, verifique la cadena con Regex o cualquier otra solución posible.
edmundo096

27

Por lo general, solo uso 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


7

Simplemente convierta la cadena dos veces:

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

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

No funciona tan mal con números enteros, pero hay muchas formas de fallar si quieres seguir este consejo con flotadores (que es sobre lo que pregunta la pregunta): "7" == "7".to_f.to_s #=> false("7" vs "7.0")
David Stosik

You can donum == num.to_i.to_s || num == num.to_f.to_s
mannykary

también puede formatear ambas cadenas usando el operador "%" para garantizar que ambas terminen en la misma cadena
Jaacko Torus

5

Sugeriría este

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" .es_a? Numérico => falso
Waclock

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

-5

Los 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

¿Qué pasa con los casos extremos? Si el número es 0 o negativo, su prueba dará un falso negativo.
tsikov

Peor aún, '1AB2' .to_i devolvería 1 para algo que claramente no es un entero ...
Thomas Bindzus
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.