3


我从数据库中的一个变量中获取日期字段,目前我正在使用以下代码检查日期是否为“yyyy-mm-dd”格式

if ( $dat =~ /\d{3,}-\d\d-\d\d/ )

我的问题是,有没有更好的方法来实现这一点。

非常感谢

4

8 回答 8

6

OWASP Validation Regex Repository的美国格式日期版本,支持闰年:

^(?:(?:(?:0?[13578]|1[02])(/|-|.)31)\1|(?:(?:0?[1,3-9]|1 [0-2])(/|-|.)(?:29|30)\2))(?:(?:1[6-9]|[2-9]\d)?\d{2 })$|^(?:0?2(/|-|.)29\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0 [48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^( ?:(?:0?[1-9])|(?:1[0-2]))(/|-|.)(?:0?[1-9]|1\d|2[0 -8])\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$

正则表达式库包含一个更简单的版本,类似于其他建议,它被转换为您的问题:

^\d{4}-\d{1,2}-\d{1,2}$
于 2009-05-13T11:19:40.223 回答
4

正如其他人所指出的,如果这是来自数据库的日期字段,则它应该采用明确定义的格式,因此您可以使用简单的正则表达式,例如 toolkit 提供的正则表达式。

但这样做的缺点是它会接受无效的日期,例如 2009-02-30。同样,如果您正在处理成功地将其转换为数据库中日期类型字段的日期,那么您应该是安全的。

一种更强大的方法是使用 CPAN 中的众多日期/时间模块之一。Date::Manip 可能是一个不错的选择,特别是检查 ParseDate() 函数。

http://metacpan.org/pod/Date::Manip

于 2009-05-13T20:31:49.590 回答
3

怎么样

/\d{2}\d{2}?-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])/
于 2009-05-13T11:06:45.923 回答
2

\d 可以匹配来自其他语言的数字字符。YYY 真的是有效的年份吗?如果它必须是四位数,破折号,两位数,破折号,两位数,我更喜欢/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/or /^[12][0-9]{3}-[0-9]{2}-[0-9]{2}$/。请注意要匹配的字符串周围的空格字符。

当然,这并没有检查那里的字符的合理性,除了第二个例子中的第一个字符。如果需要,您最好将其传递给日期解析模块,然后检查其输出以获取逻辑结果。

于 2009-05-13T11:05:29.063 回答
2

最好的轻量级解决方案是使用Date::Calccheck_date子例程,这是一个示例:

use strict;
use warnings
use Date::Calc qw[check_date];

## string in YYYY-MM-DD format, you can have any format
## you like, just parse it
my @dt_dob = unpack("A4xA2xA2",$str_dob_date);

unless(check_date(@dt_dob)) {
    warn "Oops! invalid date!";
}

我希望这会有所帮助:-)

于 2016-07-12T13:46:33.883 回答
1

那么你可以开始:

/\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|30|31)/ 
于 2009-05-13T11:05:35.723 回答
0

我强烈建议您不要编写自己的正则表达式来执行此操作。日期/时间解析很简单,但有一些棘手的方面,这是一个已经解决了数百次的问题。您无需设计、编写和调试另一个解决方案。

如果你想要一个正则表达式,最好的解决方案可能是使用我的 Regexp::Common::time 插件用于 Regexp::Common 模块。您可以指定简单或复杂、严格或模糊的日期/时间匹配,它有一个非常广泛的测试套件。

如果您只想解析特定的日期格式,最好使用 Dave Rolsky 出色的 DateTime 模块的众多解析/格式化插件之一。

如果您想在匹配后验证日期/时间值,我建议您使用 Time::Normalize 模块。

希望这可以帮助。

于 2009-05-14T20:55:47.523 回答
0

我认为使用没有外部检查的正则表达式非常复杂!我用一个小子来得到它:

sub check_date {
    my $date_string = shift;

    # Check the string fromat and get year, month and day out of it.
    # Best to use a regex.
    return 0 unless $date_string =~ m/^(\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/;
    
    # 31. in a month with 30 days
    return 0 if ($3 >= 31 and ($2 == 4 or $2 == 6 or $2  == 9 or $2 == 11));
    # February 30. or 31.
    return 0 if ($3 >= 30 and $2 == 2);
    # February 29. in not a leap year.
    return 0 if ($2 == 2 and $3 == 29
                 and not ($1 % 4 == 0 and ($1 % 100 != 0 or $1 % 400 == 0)));
    
    # Date is valid
    return 1;
}

我从regular-expressions.info得到了这个想法(以及大部分代码)。还有其他例子。

于 2021-05-27T07:20:43.640 回答