FloatingRock
FloatingRock

Reputation: 7065

How do I determine if a string is numeric?

I thought this would be easier to find, but I'm quite surprised that it isn't.

How on Earth do I test if a string is a number (including decimals) outside a Model?

e.g.

is_number("1") # true
is_number("1.234") # true
is_number("-1.45") # true
is_number("1.23aw") #false

In PHP, there was is_numeric, but I can't seem to find an equivalent in Ruby (or Rails).

So far, I've read the following answers, and haven't gotten any closer:

Upvotes: 2

Views: 5607

Answers (2)

toro2k
toro2k

Reputation: 19228

You could borrow the idea from the NumericalityValidator Rails uses to validate numbers, it uses the Kernel.Float method:

def numeric?(string)
  # `!!` converts parsed number to `true`
  !!Kernel.Float(string) 
rescue TypeError, ArgumentError
  false
end

numeric?('1')   # => true
numeric?('1.2') # => true
numeric?('.1')  # => true
numeric?('a')   # => false

It also handles signs, hex numbers, and numbers written in scientific notation:

numeric?('-10')   # => true
numeric?('0xFF')  # => true
numeric?('1.2e6') # => true

Upvotes: 7

Fred Perrin
Fred Perrin

Reputation: 1134

You could use Regular Expression.

!!("1" =~ /\A[-+]?[0-9]+(\.[0-9]+)?\z/) # true
!!("1.234" =~ /\A[-+]?[0-9]+(\.[0-9]+)?\z/) # true
!!("-1.45" =~ /\A[-+]?[0-9]+(\.[0-9]+)?\z/) # true
!!("1.23aw" =~ /\A[-+]?[0-9]+(\.[0-9]+)?\z/) # false

You can use it like this or make a method in a module or add this in the String class

class String
  def is_number?
    !!(self =~ /\A[-+]?[0-9]+(\.[0-9]+)?\z/)
  end
end

You can use this site to test your expression : Rubular: a Ruby regular expression editor and tester

I can explain much more the expression if needed.

Hope this helps.

Upvotes: 4

Related Questions