How to Test If a String Is Basically an Integer in Quotes Using Ruby

How to test if a string is basically an integer in quotes using Ruby

You can use regular expressions. Here is the function with @janm's suggestions.

class String
def is_i?
!!(self =~ /\A[-+]?[0-9]+\z/)
end
end

An edited version according to comment from @wich:

class String
def is_i?
/\A[-+]?\d+\z/ === self
end
end

In case you only need to check positive numbers

  if !/\A\d+\z/.match(string_to_check)
#Is not a positive number
else
#Is all good ..continue
end

How to check whether a string is an integer in Ruby?

If you're attempting to keep similar semantics to the original post, use either of the following:

"1234223" =~ /\A\d+\z/ ? true : false
#=> true

!!("1234223" =~ /\A\d+\z/)
#=> true

A more idiomatic construction using Ruby 2.4's new Regexp#match? method to return a Boolean result will also do the same thing, while also looking a bit cleaner too. For example:

"1234223".match? /\A\d+\z/
#=> true

Ruby: checking if a string can be converted to an integer

There's an Integer method that unlike to_i will raise an exception if it can't convert:

>> Integer("1")
=> 1
>> Integer("one")
ArgumentError: invalid value for Integer(): "one"

If you don't want to raise an exception since Ruby 2.6 you can do this:

Integer("one", exception: false)

If your string can be converted you'll get the integer, otherwise nil.

The Integer method is the most comprehensive check I know of in Ruby (e.g. "09" won't convert because the leading zero makes it octal and 9 is an invalid digit). Covering all these cases with regular expressions is going to be a nightmare.

I want to check if a variable is assigned to an integer

There is no need to check: gets returns a String, so a will never reference an Integer, it will always be a String. There is no possible way that a will ever reference an Integer in the code you posted.

Ruby is_a?(Integer) issues

params= { int1: "1" }

puts params[:int1].class

> String

Your params hash probably contains string values instead of Integers. If you want to check if a string is a valid integer, you can try validating it against a regex like so:

if /\d+/=~ params[:int1]
# do stuff
end

Ruby determine if a string only contains numbers

Try this:

def valid_pin?(pin)
/^\d{4}$/ === pin
end

What this is saying basically is:

  1. /^d{4}$/ is a regular expression, you can tell because it is enclosed in / / with a pattern in the middle
  2. the ^ and $ characters denote the beginning and end of your string, respectively. Basically what is ensures is that strings with 4 consecutive numbers but which have other characters at the beginning or end (i.e. "a1234" and "5678b") will not be accepted.
  3. \d is the regular expression character denoting digits. When followed by {4}, this means to look for exactly 4 digits. Ruby also allows you to specify a minimum value using this notation {3,} or a range {3,6}.
  4. The === method (as correctly mentioned by @iamnotmaynard), sometimes called the threequals operator, returns a boolean (true or false) value depending on whether or not the regular expression matches the given string.

In the context of your code:

puts "Please give us a 4 digit pin number for your account:"
@response = gets.chomp

unless valid_pin?(@response)
puts "Your response must be 4 numbers in length."
create_pin
else
@pin = @response.to_i
puts "Your pin has been set."
end

If you want to try and learn about Regular Expressions (commonly referred to as RegExes), I would encourage you to play around on the awesome site Rubular, there is a general keyword list and RegEx sandbox to help you text your creations.

How do I check if user input is an integer in Ruby?

The main issue with your code is String#to_i method is omnivorous.

"0".to_i #⇒ 0
"0.1".to_i #⇒ 0
"foo".to_i #⇒ 0

That said, user_input in your code is always integer.

What you probably want is to accept digits only (and maybe a leading minus for negatives.) The only concise way to accept a subset of characters is a regular expression.

# chomp to strip out trailing carriage return
user_input = gets.chomp

if user_input =~ /\A-?\d+\z/
...

The regular expression above means nothing save for digits with optional leading minus.


Or, even better (credits to @Stefan)

if gets =~ /\A-?\d+\Z/

How to validate that a string is a year

At the cost of a tiny bit of cleverness/regexp magic, something like the following will allow you to test not only for whether a string is numeric (the first criteria for being a valid year) but for whether it falls within a particular range of years:

def is_valid_year?(date_str, start=1900, end=2099)
date_str.grep(/^(\d)+$/) {|date_str| (start..end).include?(date_str.to_i) }.first
end

The above function returns nil for any string with non-numeric characters, false for those which are numeric but outside the provided range, and true for valid year strings.

Type-Conversion in Ruby

Ruby has a pretty powerful string interpolator feature using #{...} where that can contain fairly arbitrary Ruby code. The end result is always converted to a string using, effectively, to_s.

That is you can do this:

puts "00:00:#{'%02d' % i}"

Where that gets stringified and then interpolated.

This is roughly the same as:

i_str = '%02d' % i
puts "00:00:#{i_str}"

Where that is effectively:

i_str = '%02d' % i
puts "00:00:%s" % i_str

You could also combine that into a single operation:

puts "00:00:%02d" % i

Where you generally use interpolation or sprintf-style template strings, not both at the same time. It keeps your code cleaner since only one mechanism is in play.

The only reason .to_s is needed when doing concatenation is Ruby is very particular about "adding" together two things. x + y has a completely different outcome depending on what x and y are.

Consider:

# Integer + Integer (Integer#+)
1 + 2
# => 3

# Array + Array (Array#+)
[ 1 ] + [ 2 ]
# => [1,2]

# String + String (String#+)
"1" + "2"
# => "12"

Note that in each case it's actually a different method being called, and the general form of x + y is:

x.send(:+, y)

So it's actually a method call, and as such, each method may impose restrictions on what it can operate on by emitting exceptions if it can't or won't deal.



Related Topics



Leave a reply



Submit