正则表达式日期格式小于运算符

时间:2016-02-04 22:51:04

标签: ruby regex

我正在尝试使用正则表达式验证日期格式,我想检查一天是否小于32.同样,月份也小于12.我不知道如何处理它。目前,这就是我所拥有的;

^[0-1]?[0-9]{1}\-[0-3]?[0-9]{1}\-[0-9]{2,4}$

此正则表达式达到格式(m)m-(d)d-(yy)yy

4 个答案:

答案 0 :(得分:2)

TL; DR

不要将正则表达式用于比较操作。使用正则表达式拆分要比较的值,或使用实际的解析器。

使用正则表达式提取可比性

日期比较是正则表达式解决的一个非常糟糕的问题。最多,您应该使用正则表达式来提取月份中的日期以进行数值比较。例如:

date = '01-01-1970'
date.split('-')[1].to_i < 32
#=> true

但是,上面的代码并不能真正告诉您给定日期是否有效。例如,2月30日或11月31日呢?相反,您应该尝试解析日期以确定其有效性。

使用日期解析器

判断给定日期是否有效的最佳方法是使用日期解析器解析它,然后报告布尔结果或处理异常。例如,您可以尝试使用Date#parse解析日期。

布尔结果

如果您只想要一个布尔结果,可以将有效/无效的解析强制转换为true或false。例如:

require 'date'

date = '01-33-1970'
!!(Date.parse date rescue nil)
#=> false

拯救和报告例外

不太神奇,你需要从Date#parse解救ArgumentError。例如:

require 'date'

def valid_date? date_string
  true if Date.parse date_string
rescue ArgumentError => e
  STDERR.puts "#{e.class}: #{e}: '#{date_string}'"
  false
end

valid_date? '11-31-1970'

这将做你期望的事情,尽管更加冗长。例如,上面的示例将异常打印到标准错误,然后返回false作为结果。

  

ArgumentError:无效日期:'11 -31-1970'
     #=&GT;假

答案 1 :(得分:0)

^(?:[0-1][1-2]|[1-9])\-(?:3[0-1]|[0-2][1-9]|[1-9])\-[0-9]{2}(?:[0-9]{2})?$

应该做你想要的。它只允许1-12(1-9或01-12)的月份,1-31(1-9或01-31)的天数和至少2位数的年份,最多4个月。在regex101上测试。

答案 2 :(得分:0)

基本:

这是一个应该做你想做的正则表达式:

^(0[1-9]|1[0-2]|[1-9])-(0[1-9]|[1-2][0-9]|3[0-1]|[1-9])-\d{2}(\d{2})?$

匹配大于0且小于13的月份,然后是-,然后是大于0且小于32的天数,然后是-,然后是年份(2位数或4位数)。

加成:

使用验证匹配日期的完整正则表达式:

^((0?[13578]|10|12)-(([1-9])|(0[1-9])|([12])([0-9]?)|(3[01]?))-((19)([2-9])(\d{1})|(20)([01])(\d{1})|([8901])(\d{1}))|(0?[2469]|11)-(([1-9])|(0[1-9])|([12])([0-9]?)|(3[0]?))-((19)([2-9])(\d{1})|(20)([01])(\d{1})|([8901])(\d{1})))$

答案 3 :(得分:0)

如果您想确定字符串是有效日期,那么您最好尝试转换它。如果它不会转换,则无效。

def date_valid?(date_string)
  format = '%m/%d/' + (date_string.split(-).last.size == 4 ? '%Y' : '%y')
  return true if Date.strptime(date_string, format)
  rescue ArgumentError
  return false
end