0

我目前在一个 grails 项目中工作,我最终遇到了一个关于 grails 中匹配约束的问题。我的字段应该只接受一个类似日期格式的字符串,就像这样:

2012 年 10 月 25 日下午 5:00

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

4

4 回答 4

5

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

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
      }
   }
}
于 2012-05-25T06:29:38.630 回答
1

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

构建正则表达式并不困难,尤其是在您的情况下:

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

^匹配字符串的开头

$匹配字符串的结尾

\d是一个数字

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

[AP]是匹配的字符类AP

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

阅读我的博客文章每个程序员都应该知道的关于正则表达式的一些更简短的信息。

于 2012-05-25T06:19:38.557 回答
0

试试这个:^(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 指出的那样,它不会检查一个月可以有多少天。

于 2012-05-25T06:21:50.083 回答
0

尝试这个

\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

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

  1. 第一个模式找不到任何大于28二月的日期。而且它永远不会匹配任何无效的日期。
  2. 第二个与上面完全相同,但对于它来说,数字是29

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

于 2012-05-25T07:25:25.503 回答