0

尝试验证格式的日期 (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";
}
4

3 回答 3

1
-if ($test !~ m/^(\d{4})_(\d{1,2})_(\d{1,2})/)
+if ($test !~ m/^(\d{4})_(\d{1,2})_(\d{1,2})$/)
于 2012-07-30T05:15:15.113 回答
1

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

$test !~ m/^(\d{4})_(\d{1,2})_(\d{1,2})$/
于 2012-07-30T05:15:16.527 回答
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";
    }
}

注意:/smxPerl Best Practices推荐的,我用它来编写我的正则表达式,除非有特定的需要不需要它,但如果你不习惯它,它可能会让你绊倒。

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

/x只是允许正则表达式中的空格和注释,但如果你真的想匹配它,你需要转义空格。

在这种情况下,无论\z使用.$/smx

此外,查看一个模块来执行日期验证而不仅仅是日期格式验证可能不是一个坏主意(同样,这取决于您使用它的目的)。请参阅有关 perlmonks 的讨论

于 2012-07-30T06:58:57.223 回答