Topic: how to check if string is a valid number

Hi, I am looking for a isnumeric method for String. Is there something similar avaliable?

"myString".isnumeric
"32.232".isnumeric => true
"Hello".isnumeric => false

Thanks!

Re: how to check if string is a valid number

regular expressions will do.

/^[\d]+(\.[\d]+){0,1}$/ === "23.362" => true
/^[\d]+(\.[\d]+){0,1}$/ === "23.36.2" => false
/^[\d]+(\.[\d]+){0,1}$/ === "2362" => true

Re: how to check if string is a valid number

/^[\d]+(\.[\d]+){0,1}$/ === "-23.362" => true
/\A-?\d+\Z/ === "-23.362" => false

Re: how to check if string is a valid number

Duplex, using .to_f.to_s, "0" would be returned as not-a-number

Re: how to check if string is a valid number

jbartel,
I mean the other way round in my previous post. Does anybody see a problem using /\A-?\d+\Z/

/^[\d]+(\.[\d]+){0,1}$/ === "-23.362" => false
/\A-?\d+\Z/ === "-23.362" => true

Re: how to check if string is a valid number

aapte wrote:

Duplex, using .to_f.to_s, "0" would be returned as not-a-number

Your reply is confusing now as i removed my post after seeing better replies wink

anyway, your're wrong as i did a comparison which would simply return true/false:

#if self is a string:
self.to_i.to_s == self
#should return true as "1".to_i.to_s is "1"
#(for integers of course, floats are a different thing)

But regex is of course a far better solution ....

Re: how to check if string is a valid number

Duplex, to_i.to_s would work for integers only. I am looking to check floats as well. e.g. "-32.232". Reg exp is indeed a better solution.

Re: how to check if string is a valid number

Here's a revised version that works for floats too.

#!/usr/bin/ruby -w

def is_a_number?(s)

  s.to_s.match(/\A[+-]?\d+?(\.\d+)?\Z/) == nil ? false : true

end

puts is_a_number?(5)
puts is_a_number?("+256.375")
puts is_a_number?("-37.3")
puts is_a_number?("x")
puts is_a_number?(-37.3)
puts is_a_number?("2.3.3")

Re: how to check if string is a valid number

Thanks Specious,worked well!

Re: how to check if string is a valid number

Good call on the negative numbers! Glad someone caught that!

On a related note the to_f and to_i methods are almost too good. If it can't parse something it returns either 0 or the components of it that it could figure out. That leads to ambiguous results since "ASDFasdfasfd".to_i returns 0 instead of nil or raising an exception.

Re: how to check if string is a valid number

The Float() method is nice for this problem, and it catches edge cases that custom regular expressions can easily miss.

def numeric?(object)
  true if Float(object) rescue false
end

Re: how to check if string is a valid number

Nice and simple. And the rescue clause makes it bulletproof. I like it!

Re: how to check if string is a valid number

Yep, did some brief testing and I like Chap's suggestion the best.  Thanks!

My blog: www.StartBreakingFree.com
My first rails app: www.UniversityTutor.com
My second rails app: www.BuyersVote.com

Re: how to check if string is a valid number

Thanks, this was a very helpful thread - I thought I'd share my quicky bench test of the two methods because the performance results that I got was not what I expected:

arry = %w[a 1a a2 1.0b 1.1.0 0 1 1.1 0.1 -1 ]

def is_numeric?(i)
    i.to_i.to_s == i || i.to_f.to_s == i
end

def is_number?(i)
  true if Float(i) rescue false
end

a = Time.now
100000.times  { arry.each { |n| is_numeric?(n) } }
puts Time.now - a

a = Time.now
100000.times { arry.each { |n| is_number?(n) } }
puts Time.now - a

I get:
6.1308
13.1352

So explicitly creating a Float is twice as slow as converting to an integer or float and back to a string.
I also ran this with all values that would return false and got more of a 3 times slowdown, so I wonder if it has more to do with exception handling than object creation?

Re: how to check if string is a valid number

I've added is_a_number? code mentioned above to the test:

def is_a_number?(s)
  s.to_s.match(/\A[+-]?\d+?(\.\d+)?\Z/) == nil ? false : true
end

a = Time.now
100000.times { arry.each { |n| is_a_number?(n) } }
puts Time.now - a

The result is:
1.925948 is_numeric?
3.642966 is_number?
1.608794 is_a_number?
(yep, my machine is slightly faster smile )
The latter sub is the fastest one. You can win 10% more by removing to_s, but this is dangerous.

Re: how to check if string is a valid number

I know this thread is kind of old now, but I'd like to point out that the regular expression method of detection shown above does not correspond completely with the Float() method. Specifically, calling:

is_a_number?(".0")

yields false in irb (1.8.7) while Float(".0") yields 0.0 (or true using ChrisJ's is_number? method above)

For some situations, catching ".0" as valid may be important.

Likewise using either the num.to_i.to_s or num.to_f.to_s is problematic if the input may be a numeric string in a non-normalized form: "09".to_i.to_s != "9" and "5e-1".to_f.to_s != "0.5"

For these reasons I prefer the apparently slower Float() method (minzastro's is_a_number? method) better when you want to catch these valid though possibly non-normalized numeric strings.

Re: how to check if string is a valid number

Yes i wanted to know this answer, this thread is very helpful and it throws more insight to what iam looking for.

Re: how to check if string is a valid number

I know this is old, but wanna see something cool?

begin Float("Test") ; true end rescue false

returns false

Or as a one-liner extension to Number:

class String
  def is_numeric?
    begin Float(self) ; true end rescue false
  end
end

Or, more readable:

class String
  def is_numeric?
    Float(self)
    true 
  rescue 
    false
  end
end

Works for floats, and specifically why I was interested - works for "0" just fine. (string.to_f does not, as "0".to_f == 0 and "Anything".to_f == 0)

Re: how to check if string is a valid number

Float not working perfect :
because float number 545e5 is correct
true if Float("545e5") rescue false
=> true

Last edited by pauliuspr (2012-10-19 07:32:29)

Re: how to check if string is a valid number

string.is_a? Integer