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
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
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.
randy_k
October 25, 2007, 7:59pm
10
One caveat is that integers can have alpha characters in the string,
e.g. hex.
p ‘2a’.to_i(16) # => 42
randy_k
October 25, 2007, 7:52pm
11
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.
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
randy_k
October 25, 2007, 8:15pm
12
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
randy_k
October 26, 2007, 12:02am
13
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:
“+010” is unchanged and will yield 8 instead of 10
same for negative numbers
“00” will be converted to “” which will trigger an error
you use gsub although the regular expression can match only once
Subtle, subtle…
Kind regards
robert
randy_k
October 25, 2007, 8:51pm
14
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
randy_k
October 27, 2007, 11:44pm
15
I usually use a quick and dirty hack to avoid regexps (though they’re
nice.
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