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