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

Randy K. 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

Randy K. 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

Alle giovedì 25 ottobre 2007, Randy K. ha scritto:

Randy K.

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

If s is a string:

s[/^\d+$]

Hi –

On Fri, 26 Oct 2007, Randy K. 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.

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

Daniel W. 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

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

Daniel W. wrote:
—<good stuff (in this and the other replies) omitted>----

Thanks to all who replied!

Randy K.

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

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

Randy K. 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 K.

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

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

On 25.10.2007 18:54, Stefano C. wrote:

Thanks!

I hope this helps

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

Hi –

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

end
Although…

strings = [“0025\nhello”] # will print 25

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

David

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