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

R

Randy Kramer

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
 
D

Daniel Waite

Randy said:
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
 
T

Tim Hunter

Randy said:
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
 
S

Stefano Crocco

Alle gioved=EC 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=20
the wrong format. The only problem lies in the fact that it treats a string=
=20
with leading zeros as an octal number (for example, Integer("000123") gives=
=20
83). To avoid this, you can use gsub on the string:

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

I hope this helps
 
D

David A. Black

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

--
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!
 
J

Jim Clark

Daniel said:
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
 
7

7stud --

Randy said:
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. :)

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
 
7

7stud --

7stud said:
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
 
L

Lloyd Linklater

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


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

7stud --

7stud said:
7stud said:
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
 
D

David A. Black

Hi --

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!
 
R

Robert Klemme

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

Kernel.Integer can convert a string to a number raising an exception ifit 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'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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,763
Messages
2,569,562
Members
45,038
Latest member
OrderProperKetocapsules

Latest Threads

Top