Aleksandra Nowak
Aleksandra Nowak

Reputation: 57

Validating user input (string) using Ruby

I want to make sure that the only input from user is 8 numbers ( input will be by default integer ).

My goal is to make sure that user is inputting date in format: yyyymmdd .

If he won't input this format I want to use loop to make input once again until he will put correct format ( yyyymmdd ).

My current loop does not validate the date, it passes every input.

txt=gets

re1='((?:(?:[1]{1}\\d{1}\\d{1}\\d{1})|(?:[2]{1}\\d{3}))(?:[0]?[1-9]|[1][012])(?:(?:[0-2]?\\d{1})|(?:[3][01]{1})))(?![\\d])' # YYYYMMDD 1

re=(re1)
m=Regexp.new(re,Regexp::IGNORECASE);

while m.match(txt) 
  txt=gets
end

Upvotes: 1

Views: 1825

Answers (2)

dawg
dawg

Reputation: 103844

Try something along these lines:

require 'date'
d=nil
loop do
   puts 'Enter date YYYYMMDD'
   st = gets.chomp
   if st.match('^(\d\d\d\d)(\d\d)(\d\d)$')
      begin
          d=Date.strptime("#{$1}/#{$2}/#{$3}", '%Y/%m/%d')
          break
      rescue ArgumentError
          puts 'BAD DATE!'
      end  
   end 
end

puts d

But personally, I would change the regex so the user can enter a date line these:

2014/2/2
2015 12 25
1999-2-02

The regex for that is:

^\D*(\d\d\d\d)\D+(\d\d?)\D+(\d\d?)\D*$

Demo

Then a delimiter is required between that elements of the date. Any non-digit will do.

Updated code:

require 'date'
d=nil
loop do
   puts 'Enter date YYYY-MM-DD'
   st = gets.chomp
   if st.match('^\D*(\d\d\d\d)\D+(\d\d?)\D+(\d\d?)\D*$')
      begin
          d=Date.strptime("#{$1}/#{$2}/#{$3}", '%Y/%m/%d')
          break
      rescue ArgumentError
          puts 'BAD DATE!'
      end  
   end 
end

puts d

Upvotes: 1

Myst
Myst

Reputation: 19221

Here is a usable Regexp:

regexp = /([0-9]+{4})((0[1-9]+)|(1[0-2]+))(([0-2]+[0-9]+)|(3[0-1]+))/
m = regexp.match '19990531'
m[1] #=> 1999, year
m[2] #=> 05, month
m[5] #=> 31, day

I would probably accept the solution suggested by @alfasin, it make sense and allows for different formats...

...BUT, you should be aware that different locales enter the date in different ways and that using the Date.parse method might produce unexpected results. for instance, 1.2 is February 1st in the EU, while it is January 2nd in the USA...

Upvotes: 0

Related Questions