Ruby Regular Expression用于验证日期的日期和月份

时间:2017-05-05 17:20:54

标签: ruby-on-rails ruby

rubular上我测试并确认这可以很好地确认日期条目的所需格式

\A\d\d\/\d\d\/\d\d\d\d\z

试验:

01/02/2000 #pass
11/21/2014 #pass
11-21-2014 #fail
A3-21-2014 #fail

我想让它变得更好一些,对我来说这对我来说已经足够了。我想要的是确认“月份字段”(前两位数)是01到12之间的任何位置,其中每个数字由零引导。 (例如:01,02,03等,而不是:1,2,3)。

接下来:我想对接下来的两位数字做同样的事情,以确认接下来的两位数字(日期字段)介于01-31之间。同样的事情:每一位数都需要以零为首。

试验:

01/02/2017 #pass
12/31/2017 #pass
1/02/2017  #fail
01/2/2017  #fail
50/01/2017 #fail
01/50/2017 #fail

我意识到这个正则表达式对于那些少于31天的月份来说是不准确的,但它对我正在做的事情来说已经足够了。

2 个答案:

答案 0 :(得分:1)

由于投票不足,我考虑删除这个问题。我选择不删除这个问题,因为其他人可能跟我一样走路,我想我可以提供一个很好的解决方案。

我所做的是使用american_date宝石。在您的日期输入:用户应以以下格式输入日期:" mm / dd / yyyy"。

为了强制用户以这种格式输入日期:我使用了jquery-inputmask-rails。我这样定义了我的面具:

$('.mask_american_date').inputmask({mask: "99/99/9999"});

现在日期输入上会有一个很好的掩码,如下所示:

__/__/____

现在:您只需要模型中日期字段的状态验证器:

validates_presence_of :date_of_birth, message: "Date is either invalid or is not present".

这涵盖了一切。美国日期的工作原理是用户输入并尝试将其转换为日期。如果由于任何原因无法将用户输入转换为日期:它将返回nil,从而触发上述验证。

  • 这包括错误的月份入口或糟糕的一天入口。例如,American Date足够聪明,知道9月只有30天。所以:如果用户输入" 31"对于当天部分,例如:09/31/2017,美国日期会将日期转换为nil

答案 1 :(得分:1)

嗯,这应该可以让你大部分时间到处:

/((02\/[0-2]\d)|((01|[0][3-9]|[1][0-2])\/(31|30|[0-2]\d)))\/[12]\d{3}/

当然,它没有处理以下内容:

  • 闰年,例如无论年度如何,02/29都可以接受
  • 1000-2999的所有年份都可以接受
  • 只有30天的月份,例如09/31是可以接受的

案例链接中的小细分:

这是Rubular的跳动 以下是Regex101

的解释
  • (02\/[0-2]\d) - 从02开始/然后允许0-2,然后是0-9
  • OR ((01|[0][3-9]|[1][0-2]\/(31|30|[0-2]\d)) - 从(01或0后跟3-9或1后跟0-2)开始,然后是/或后跟31或30或0-2,然后是0-9
  • 在这两种情况下,必须跟随1或2,然后是3位数字0-9

真的希望ruby支持像真正的pcre Example for edification

这样的条件

作为一个注释:正如评论中所提到的那样,解析一个解析失败可能比使用一个正则表达式更容易,但我想你问了。