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?


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


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


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


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

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

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

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.