带有日期的perl正则表达式

时间:2012-07-30 05:13:27

标签: perl

尝试验证格式的日期(YYYY_MM_DD)。将测试变量设置为2012_4_123,在脚本运行后打印“有效格式”。它应该给出“无效错误”消息,因为在正则表达式中,日期部分被检查为至少1位数且不超过2位数。不确定它是如何打印“有效格式”作为输出消息。

my $test="2012_4_123";
if ($test !~ m/^(\d{4})_(\d{1,2})_(\d{1,2})/)
{
  print "invalid format\n";
}
else
{
 print  "valid format\n";
}

3 个答案:

答案 0 :(得分:1)

-if ($test !~ m/^(\d{4})_(\d{1,2})_(\d{1,2})/)
+if ($test !~ m/^(\d{4})_(\d{1,2})_(\d{1,2})$/)

答案 1 :(得分:1)

你最后错过了$。它匹配字符串"2012_4_12",因为你没有告诉它匹配字符串的结尾。你的正则表达式应该是这个。

$test !~ m/^(\d{4})_(\d{1,2})_(\d{1,2})$/

答案 2 :(得分:1)

简单地添加$解决了当天允许超过两位数的初始问题,但引入了一个更微妙的错误:尽管最后有一个换行符,但日期现在会验证。这可能无关紧要取决于您的应用程序,但可以通过使用以下示例中的正则表达式来避免:

use strict;
use warnings;

my @tests = (
    '2012_4_123',
    '2012_11_22',
    "2012_11_22\n",
);

use Data::Dumper;
print Dumper \@tests;

foreach my $test (@tests) {
    if ( $test !~ m/\A(\d{4})_(\d{1,2})_(\d{1,2})\z/smx )
    {
        print "invalid format\n";
    }
    else
    {
        print "valid format\n";
    }
}

注意: Perl最佳实践建议使用/smx,我会用它编写我的正则表达式,除非特别需要它,但是如果你是的话它可能会让你失望不习惯。

/s/m将允许您更轻松地处理多行字符串; /s因为.会匹配换行符和/m,因此您可以分别使用^$来匹配行的开头和结尾,{然后,{1}}和\A将匹配整个字符串的开头和结尾。

\z只是允许在正则表达式中使用空格和注释,但如果你真的想要匹配它,你将需要转义空格。

在这种情况下,无论使用/x,都会使用\z而不是$来产生差异。

此外,查看模块以执行日期验证而不仅仅是日期格式验证(再次,取决于您使用它的目的)可能不是一个坏主意。请参阅此discussion on perlmonks