2015-05-04 3 views
1

Я хочу, чтобы единственный вход пользователя был 8 чисел (вход будет по умолчанию целочисленным).Проверка ввода пользователя (строки) с использованием Ruby

Моя цель - убедиться, что пользователь вводит дату в формате: yyyymmdd.

Если он не будет вводить этот формат, я хочу использовать цикл для ввода ввода еще раз, пока он не установит правильный формат (yyyymmdd).

Моя текущая петля не проверяет дату, она передает каждый вход.

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 
+1

Нет необходимости в регулярных выражениях валидаций (которые являются сложными и медленно), просто попытаться разобрать дату и, если исключение, поймать его, отображать Сообща ошибку и попросить пользователь для повторного ввода даты (сделать это в цикле, который ломается только при вводе действительной даты) – alfasin

ответ

1

попробовать что-то вдоль этих линий:

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 

Но лично я хотел бы изменить регулярное выражение, так что пользователь можно ввести дату линии эти:

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

регулярное выражение для этого есть:

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

Demo

Затем между этими элементами даты требуется разделитель. Любая несимметрия будет делать.

Обновленный код:

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 
+0

Благодарим dawg, ваш код соблюдает високосный год и проходит тестирование. –

0

Вот полезная 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 

я, вероятно, примет решение, предложенное @alfasin, оно имеет смысл и позволяет использовать различные форматы ...

... НО , вы должны знать, что разные локали вводят дату по-разному и что использование метода Date.parse может привести к неожиданным результатам. например, 1,2 является 1 февраля в ЕС, в то время как он 2 января в США ...

Смежные вопросы