【问题标题】:Regex validation grails date-like format正则表达式验证 grails 类日期格式
【发布时间】:2012-05-25 06:04:33
【问题描述】:

我目前正在从事一个 grails 项目,但最终遇到了有关 grails 中匹配约束的问题。我的字段应该只接受一个类似日期格式的字符串:

2012 年 10 月 25 日下午 5:00

这可能在使用正则表达式的匹配约束中吗?我总是很难使用正则表达式进行数据过滤,因为这有点令人困惑。

【问题讨论】:

  • 我认为使用正则表达式匹配日期时间不是一个好主意。而是查看语言/框架是否提供了日期时间函数,该函数接受字符串、格式字符串并将其转换为日期/时间对象,如果不能,则返回 false。

标签: regex grails pattern-matching grails-constraints


【解决方案1】:

如果是数据,为什么不使用标准日期格式化程序对其进行验证?喜欢:

static constraints = {
   mydate validator: {
      try {
         Date.parse('MM-dd-yyyy hh:mma', it)
         return true
      } catch (ParseException e) {
         return false
      }
   }
}

顺便说一句,在这种情况下,Date 可以解析不太有效的日期(并将其转换为正确的值,例如 15am3pm)。如果您需要完全有效的格式,您可以将其与原始值进行比较:

static constraints = {
   mydate validator: {
      try {
         Date date = Date.parse('MM-dd-yyyy hh:mma', it)
         return Date.format('MM-dd-yyyy hh:mma', date) == it
      } catch (ParseException e) {
         return false
      }
   }
}

或者您可以使用SimpleDateFormat 代替:

final static DateFormat DATEFORMAT = new SimpleDateFormat('MM-dd-yyyy hh:mma') 

static constraints = {
   mydate validator: {
      try {
         Date date = DATEFORMAT.parse(it)
         return DATEFORMAT.format(date) == it
      } catch (ParseException e) {
         return false
      }
   }
}

【讨论】:

    【解决方案2】:

    没有可以使用的 Date 对象吗?我不知道,但我可以帮助你处理正则表达式:

    构造一个正则表达式并不难,尤其是在你的情况下:

    ^\d{2}-\d{2}-\d{4} \d{2}:\d{2}[AP]M$
    

    ^匹配字符串的开头

    $匹配字符串的结尾

    \d 是一个数字

    {2} 是一个量词,使前一个字符需要 2 次​​p>

    [AP] 是匹配AP 的字符类

    这个正则表达式只检查格式,而不是数字是否代表有效的日期或时间!(例如 99-99-0000 35:61PM 是有效的)

    阅读我的博文What absolutely every Programmer should know about regular expressions 了解更多简要信息。

    【讨论】:

      【解决方案3】:

      试试这个:^(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])-((?:19|20)\d\d) ([0-1]?[0-9]|2[0-4]):([0-5][0-9])(?::([0-5][0-9]))?(AM|PM)$

      ^ Start of string
          (0[1-9]|1[012]) Month
          -
          (0[1-9]|[12][0-9]|3[01]) Day
          -
          ((?:19|20)\d\d) Year
      
          ([0-1]?[0-9]|2[0-4]) HH
          :
          ([0-5][0-9]) MM
          (?::([0-5][0-9]))? optional :SS
          (AM|PM)
      $ End of string
      

      它捕获月、日、年、小时、分钟、秒和 AM/PM。

      编辑:正如 Vikas 指出的那样,它不会检查一个月可以有多少天。

      【讨论】:

      • 它会很乐意接受02-31-2012 5:00PM作为有效日期。
      【解决方案4】:

      试试这个

      \b(?:(?:(?:0?[469]|11)\-(?:0?(?:[1-9]|[12][0-9])|30)\-(?:1[7-9][0-9]{2}|200[0-9]|201[0-2]))|(?:(?:0?[13578]|1[02])\-(?:0?(?:[1-9]|[12][0-9])|3[01])\-(?:1[7-9][0-9]{2}|200[0-9]|201[0-2]))|(?:(?:0?2)\-(?:0?(?:[1-9]|1[0-9])|2[0-8])\-(?:1[7-9][0-9]{2}|200[0-9]|201[0-2]))) +(?:(?:(?:0?([0-9])|1[0-2])):(?:0?([0-9])|[1-5][0-9])(?:[AP]M))\b
      

      \b(?:(?:(?:0?[469]|11)\-(?:0?(?:[1-9]|[12][0-9])|30)\-(?:1[7-9][0-9]{2}|200[0-9]|201[0-2]))|(?:(?:0?[13578]|1[02])\-(?:0?(?:[1-9]|[12][0-9])|3[01])\-(?:1[7-9][0-9]{2}|200[0-9]|201[0-2]))|(?:(?:0?2)\-(?:0?(?:[1-9]|1[0-9])|2[0-9])\-(?:1[7-9][0-9]{2}|200[0-9]|201[0-2]))) +(?:(?:(?:0?([0-9])|1[0-2])):(?:0?([0-9])|[1-5][0-9])(?:[AP]M))\b
      

      注意:两种模式都有一个共同的限制,即如果monthfebruary,它将匹配无效的dates。 If-else 条件在某些 RegEx 风格中被接受,但不存在用于算术运算的此类函数。可能在不久的将来,这可能会在某些 RegEx 风格中实现,但我认为 RegEx 基本上不是这种情况。

      1. 第一个模式找不到任何大于二月份的28 的日期。而且它永远不会匹配任何无效的日期。
      2. Second 和上面的一模一样,但是它的数字是29

      众所周知,使用 RegEx 无法完全解决此问题。

      【讨论】:

        猜你喜欢
        • 2014-03-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多