Change a string to an integer, report an error if the string does not represent an integer?

Can anybody point me to a way to check if a string represents a valid integer
and then convert it to an integer?

It is very likely the string will contain leading zeros, and should not
contain any trailing non-numeric characters.

Per the documentation (pickaxe 2), to_i won't quite do it, it will just ignore
trailing non-numeric characters.

Thanks!

Randy Kramer

Randy Kramer wrote:

Can anybody point me to a way to check if a string represents a valid
integer
and then convert it to an integer?

It is very likely the string will contain leading zeros, and should not
contain any trailing non-numeric characters.

Per the documentation (pickaxe 2), to_i won't quite do it, it will just
ignore
trailing non-numeric characters.

match = '000345'.match(/^\d+$/) # MatchData
match[0] # "000345"

match = '0003b45aa'.match(/^\d+$/) # nil
match # nil

···

--
Posted via http://www.ruby-forum.com/\.

Randy Kramer wrote:

Can anybody point me to a way to check if a string represents a valid
integer
and then convert it to an integer?

It is very likely the string will contain leading zeros, and should not
contain any trailing non-numeric characters.

Per the documentation (pickaxe 2), to_i won't quite do it, it will just
ignore
trailing non-numeric characters.

Check out Kernel#Integer

···

--
Posted via http://www.ruby-forum.com/\.

Alle giovedì 25 ottobre 2007, Randy Kramer ha scritto:

Can anybody point me to a way to check if a string represents a valid
integer and then convert it to an integer?

It is very likely the string will contain leading zeros, and should not
contain any trailing non-numeric characters.

Per the documentation (pickaxe 2), to_i won't quite do it, it will just
ignore trailing non-numeric characters.

Thanks!

Randy Kramer

Kernel.Integer can convert a string to a number raising an exception if it has
the wrong format. The only problem lies in the fact that it treats a string
with leading zeros as an octal number (for example, Integer("000123") gives
83). To avoid this, you can use gsub on the string:

Integer("000123".gsub(/^0+/,''))
=> 123

I hope this helps

Hi --

Can anybody point me to a way to check if a string represents a valid integer
and then convert it to an integer?

It is very likely the string will contain leading zeros, and should not
contain any trailing non-numeric characters.

Per the documentation (pickaxe 2), to_i won't quite do it, it will just ignore
trailing non-numeric characters.

There's a method called Integer (uppercase I and all). It blows up if
the string has extra stuff:

irb(main):001:0> Integer("0003")
=> 3
irb(main):002:0> Integer("0003a")
ArgumentError: invalid value for Integer: "0003a"

David

···

On Fri, 26 Oct 2007, Randy Kramer wrote:

--
Upcoming training by David A. Black/Ruby Power and Light, LLC:
   * Advancing With Rails, Edison, NJ, November 6-9
   * Advancing With Rails, Berlin, Germany, November 19-22
   * Intro to Rails, London, UK, December 3-6 (by Skills Matter)
See http://www.rubypal.com for details!

Randy Kramer wrote:

Can anybody point me to a way to check if a string represents a valid
integer
and then convert it to an integer?

It is very likely the string will contain leading zeros, and should not
contain any trailing non-numeric characters.

Per the documentation (pickaxe 2), to_i won't quite do it, it will just
ignore
trailing non-numeric characters.

Thanks!

Randy Kramer

Integers can also be negative.

Integers can also have leading '+' signs. :slight_smile:

Another way:

def valid_int?(str)
  start = true

  str.each_byte do |char|
    if start
      start = false
      if char == ?+ or char == ?-
        next
      end
    end

    if char < ?0 or char > ?9
      return false
    end
  end

  return true
end

strings = ['0013abc', '0025', '-0030', '+051', '00-1', '-abc72']
strings.each do |str|
  if valid_int?(str)
    puts str.to_i
  else
    puts 'invalid int'
  end
end

···

--
Posted via http://www.ruby-forum.com/\.

One caveat is that integers can have alpha characters in the string,
e.g. hex.

p '2a'.to_i(16) # => 42

···

--
Posted via http://www.ruby-forum.com/.

Daniel Waite wrote:

match = '000345'.match(/^\d+$/) # MatchData
match[0] # "000345"

match = '0003b45aa'.match(/^\d+$/) # nil
match # nil
  

Integers can also be negative. Not sure if this applies to your case but if so, change the regex to something like:

match = '-000345'.match(/^\-*\d+$/) # MatchData
match[0] # "-000345"

match = '000345'.match(/^\-*\d+$/) # MatchData
match[0] # "000345"

match = '0003b45aa'.match(/^\-*\d+$/) # nil
match # nil

Regards,
Jim

7stud -- wrote:

  str.each_byte do |char|
    if start
      start = false
      if char == ?+ or char == ?-
        next
      end
    end

    if char < ?0 or char > ?9
      return false
    end
  end

  return true
end

strings = ['0013abc', '0025', '-0030', '+051', '00-1', '-abc72']
strings.each do |str|
  if valid_int?(str)
    puts str.to_i
  else
    puts 'invalid int'
  end
end

--output:--
invalid int
25
-30
51
invalid int
invalid int

···

--
Posted via http://www.ruby-forum.com/\.

I'd rather do

Integer(s.sub(/\A([+-]?)0+(?=.)/, '\\1'))

because your regexp has some issues:

1. "+010" is unchanged and will yield 8 instead of 10

2. same for negative numbers

3. "00" will be converted to "" which will trigger an error

4. you use gsub although the regular expression can match only once

Subtle, subtle...

Kind regards

  robert

···

On 25.10.2007 18:54, Stefano Crocco wrote:

Alle giovedì 25 ottobre 2007, Randy Kramer ha scritto:

Can anybody point me to a way to check if a string represents a valid
integer and then convert it to an integer?

It is very likely the string will contain leading zeros, and should not
contain any trailing non-numeric characters.

Per the documentation (pickaxe 2), to_i won't quite do it, it will just
ignore trailing non-numeric characters.

Thanks!

Randy Kramer

Kernel.Integer can convert a string to a number raising an exception if it has the wrong format. The only problem lies in the fact that it treats a string with leading zeros as an octal number (for example, Integer("000123") gives 83). To avoid this, you can use gsub on the string:

Integer("000123".gsub(/^0+/,''))
=> 123

I hope this helps

I usually use a quick and dirty hack to avoid regexps (though they're nice.
:slight_smile:

def is_integer(to_test)
    begin
      Integer(to_test)
      return true
    rescue ArgumentError
      return false
    end
  end

Basically, I think whoever wrote the Integer-class is smarter than me, so
why not let them figure it out?
It's probably an abuse of exceptions, but it works just fine.

Regards,

Søren Andersen

···

On 10/25/07, Lloyd Linklater <lloyd@2live4.com> wrote:

One caveat is that integers can have alpha characters in the string,
e.g. hex.

p '2a'.to_i(16) # => 42
--
Posted via http://www.ruby-forum.com/\.

---<good stuff (in this and the other replies) omitted>----

Thanks to all who replied!

Randy Kramer

···

On Thursday 25 October 2007 01:13 pm, Jim Clark wrote:

Daniel Waite wrote:

7stud -- wrote:

7stud -- wrote:

  str.each_byte do |char|
    if start
      start = false
      if char == ?+ or char == ?-
        next
      end
    end

    if char < ?0 or char > ?9
      return false
    end
  end

  return true
end

strings = ['0013abc', '0025', '-0030', '+051', '00-1', '-abc72']
strings.each do |str|
  if valid_int?(str)
    puts str.to_i
  else
    puts 'invalid int'
  end
end

--output:--
invalid int
25
-30
51
invalid int
invalid int

Ugh. This is much faster:

strings = ['0013abc', '0025', '-0030', '+051', '00-1', '-abc72']

strings.each do |str|
  if str.match(/^(\-|\+)?\d+$/)
    puts str.to_i
  else
    puts "invalid int"
  end
end

···

--
Posted via http://www.ruby-forum.com/\.

Hi --

···

On Fri, 26 Oct 2007, 7stud -- wrote:

Ugh. This is much faster:

strings = ['0013abc', '0025', '-0030', '+051', '00-1', '-abc72']

strings.each do |str|
if str.match(/^(\-|\+)?\d+$/)
   puts str.to_i
else
   puts "invalid int"
end
end

Although....

   strings = ["0025\nhello"] # will print 25

You want \A and \z, rather than ^ and $.

David

--
Upcoming training by David A. Black/Ruby Power and Light, LLC:
   * Advancing With Rails, Edison, NJ, November 6-9
   * Advancing With Rails, Berlin, Germany, November 19-22
   * Intro to Rails, London, UK, December 3-6 (by Skills Matter)
See http://www.rubypal.com for details!