1

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:

Community
  • 1
  • 1
FloatingRock
  • 6,741
  • 6
  • 42
  • 75

2 Answers2

7

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
toro2k
  • 19,020
  • 7
  • 64
  • 71
4

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.

Fred Perrin
  • 1,124
  • 2
  • 17
  • 23