109 votes

Comment puis-je vérifier si une valeur est un nombre ?

Je veux simplement vérifier si une valeur renvoyée d'un champ de texte de formulaire est un numéro, c'est-à-dire 12, 12.5 ou 12,75. Y a-t-il un moyen simple de vérifier ceci, surtout si la valeur est extraite en tant que param ?

0 votes

Um, la seule chose est que le code fonctionne pour is_a_number? fonctionne avec la seule exception étant des nombres .02 ou .3....

7 votes

Je préfère beaucoup cette solution : stackoverflow.com/questions/5661466/… Je ne sais pas pourquoi tant de gens pensent qu'une expression régulière serait meilleure pour cela.

244voto

Peter Points 38320

Vous pouvez utiliser

12.is_a? Numeric

(Numeric fonctionnera pour les entiers et les nombres décimaux.)

Si cela arrive sous forme de chaîne de caractères qui pourrait contenir une représentation d'un nombre valide, vous pourriez utiliser

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

et ensuite '12'.valid_float? retournera true si vous pouvez convertir la chaîne en un flottant valide (par exemple, avec to_f).

0 votes

Désolé, c'est Ruby on Rails ... Fondamentalement, je veux juste être capable d'évaluer n'importe quelle entrée de l'utilisateur que ce soit .03 0.3, 2.2. Les deux dernières fonctionnent, mais j'ai besoin de faire fonctionner la première entrée :S

10 votes

Fixnum ne semble pas fonctionner avec les nombres décimaux. Cependant, Numeric fonctionne correctement. Donc 1.234.is_a? Fixnum == false, mais 1.234.is_a? Numeric == true.

0 votes

Cela ne fonctionne pas avec les floats. Devrait utiliser 1.1.is_a? Numeric Voir stackoverflow.com/a/17668654/76486

32voto

daesu Points 133

Je utilise généralement simplement Integer et Float ces jours-ci.

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

3 votes

Dans Ruby 2.6, vous pouvez également faire ce qui suit: Integer('343', exception: false) # 343 et Integer('fg5', exception: false) # nil ```

30voto

cwninja Points 5041

Il suffit de l'exprimer régulièrement, c'est trivial, et cela ne vaut pas la peine d'y réfléchir au-delà :

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

(Corrigé selon le commentaire de Justin)

6 votes

En Ruby, ^ et $ désignent le début/la fin d'une ligne, non d'une chaîne de caractères. Ceci rend cette méthode inefficace pour nettoyer les entrées (voir guides.rubyonrails.org/security.html#regular-expressions). Une meilleure approche serait : v.to_s =~ /\A[-+]?\d*\.?\d+\z/.

0 votes

Cela ne fonctionne pas pour les chaînes qui représentent une notation exponentielle irb(main):031:0> v = "0.7e1" => "0.7e1" irb(main):032:0> v =~ /\A[-+]?[0-9]*\.?[0-9]+\Z/ => nil

16voto

ryanprayogo Points 5058

Vous pouvez ajouter un :

validates_numericality_of :the_field

dans votre modèle.

Voir : http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html#M002172

12voto

Evan Ross Points 705

Il suffit de convertir la chaîne deux fois :

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

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

1 votes

Ça fonctionne plutôt bien avec les entiers, mais il y a tellement de façons d'échouer si vous voulez suivre ce conseil avec des nombres décimaux (ce que la question demande) : "7" == "7".to_f.to_s #=> false ("7" vs "7.0")

0 votes

Vous pouvez faire num == num.to_i.to_s || num == num.to_f.to_s

0 votes

Vous pouvez également formater les deux chaînes en utilisant l'opérateur "%" pour garantir qu'elles se terminent toutes deux par la même chaîne

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X