Wie kann ich überprüfen, ob ein Wert eine Zahl ist?

82

Ich möchte einfach überprüfen, ob ein zurückgegebener Wert aus einem Formulartextfeld eine Zahl ist, dh: 12, 12.5 oder 12.75. Gibt es eine einfache Möglichkeit, dies zu überprüfen, insbesondere wenn der Wert als gezogen wird param?

user211662
quelle
ähm, das einzige ist, dass der Code für is_a_number funktioniert? funktioniert mit der einzigen Ausnahme, .02 oder .3 Zahlen ....
user211662
7
Ich bevorzuge diese Lösung sehr: stackoverflow.com/questions/5661466/… Ich weiß nicht, warum so viele Leute denken, dass ein regulärer Ausdruck dafür besser wäre.
2called-Chaos

Antworten:

26

Regexp es einfach, es ist trivial und es lohnt sich nicht darüber nachzudenken:

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

(Behoben gemäß Justins Kommentar)

cwninja
quelle
5
In Ruby bezeichnen ^ und $ den Anfang / das Ende einer Zeile, nicht einer Zeichenfolge. Dies macht es unwirksam, Eingaben zu bereinigen (siehe guide.rubyonrails.org/security.html#regular-expressions ). Ein besserer Ansatz wäre : v.to_s =~ /\A[-+]?\d*\.?\d+\z/.
Justin
204

Sie können verwenden

12.is_a? Numeric

( Numericfunktioniert für Ganzzahlen und Gleitkommazahlen.)

Wenn es als Zeichenfolge ankommt, die möglicherweise eine Darstellung einer gültigen Zahl enthält, können Sie es verwenden

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

und gibt dann '12'.valid_float?true zurück, wenn Sie die Zeichenfolge in einen gültigen float konvertieren können (z to_f. B. mit ).

Peter
quelle
Entschuldigung, das ist Ruby on Rails ... Grundsätzlich möchte ich nur in der Lage sein, alle Eingaben des Benutzers zu bewerten, ob es .03 0.3, 2.2 sind. Die beiden letzteren funktionieren, aber ich muss die erste Eingabe zum Laufen bringen: S
user211662
10
Fixnumscheint nicht mit Schwimmern zu funktionieren. Funktioniert jedoch Numericgut. Also 1.234.is_a? Fixnum == false, aber 1.234.is_a? Numeric == true.
KurtPreston
Dies funktioniert nicht mit Schwimmern. Sollte verwenden 1.1.is_a? NumericSiehe stackoverflow.com/a/17668654/76486
Brian Armstrong
1
Arbeitet nicht für mich :(pry(main)> '12'.is_a? Numeric => false
Salil
@ Salil offensichtlich wird das bei dir nicht funktionieren, '12'ist ein String. Überprüfen Sie in diesem Fall die Zeichenfolge mit Regex oder einer anderen möglichen Lösung.
edmundo096
27

Normalerweise benutze ich heutzutage nur Integer und Float.

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
daesu
quelle
6

Konvertieren Sie den String einfach zweimal:

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

num = '3re'
num == num.to_i.to_s 
#=> false
Evan Ross
quelle
Funktioniert nicht so schlecht mit ganzen Zahlen, aber es gibt so viele Möglichkeiten, um zu scheitern, wenn Sie diesen Rat mit Floats befolgen möchten (worum es in der Frage geht): "7" == "7".to_f.to_s #=> false("7" vs "7.0")
David Stosik
Sie können tunnum == num.to_i.to_s || num == num.to_f.to_s
Mannykary
Sie können beide Zeichenfolgen auch mit dem Operator "%"
formatieren, um sicherzustellen,
5

Ich würde diesen vorschlagen

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
installero
quelle
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
Brian Armstrong
quelle
6
"1.1" .is_a? Numerisch => falsch
Waclock
Wie würden Sie das Problem der String-Konvertierung angehen? OP gibt an, dass es aus einem Textfeld stammt.
Schlingel
-5

String-Werte werden mit .to_i immer in 0 konvertiert

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

[15] pry(main)> '101'.to_i > 0
=> true
Adrian Teh
quelle
Was ist mit Randfällen? Wenn die Zahl 0 oder negativ ist, ergibt Ihr Test ein falsches Negativ.
Tsikov
Noch schlimmer wäre, dass '1AB2'.to_i 1 für etwas zurückgeben würde, das eindeutig keine Ganzzahl ist ...
Thomas Bindzus