我正在设置此示例Perl片段以验证日期中的几个月:
我想接受的一些场景是:
MM M
#!/usr/bin/perl
use strict;
use warnings;
my $pattern;
my $month = "(0[1-9]|1[012])";
my $day = "(0[1-9]|[12]\d|3[01])";
system("cls");
do {
print "Enter in a month: ";
chomp($pattern = <STDIN>);
# We only want to print if the pattern matches
print "Pattern matches\n" if ($pattern =~ /$month/);
} while ($pattern ne "Q");
Run Code Online (Sandbox Code Playgroud)
当我运行它时,它正确地从01-12过滤但是当我将正则表达式更改为:
$month = "(0?[1-9]|1[012])";
Run Code Online (Sandbox Code Playgroud)
然后正则表达式允许13,14等...给出了什么?
YOU*_*YOU 34
如果你真的想使用正则表达式,你需要把^和$,就像
"^(0?[1-9]|1[012])$"
它不会匹配13,14 ....
Gre*_*ill 18
您不应使用正则表达式进行数值范围验证.你想要的正则表达式是:
/^(\d+)$/
Run Code Online (Sandbox Code Playgroud)
然后,
if ($1 >= 1 && $1 <= 12) {
# valid month
}
Run Code Online (Sandbox Code Playgroud)
这比任何正则表达式更容易阅读以验证数值范围.
另外,Perl通过在目标中搜索匹配的表达式来评估正则表达式.所以:
/(0[1-9]|1[012])/
Run Code Online (Sandbox Code Playgroud)
搜索0后跟1到9,或1搜索后跟0,1或2.例如,这将匹配"202"和许多其他数字.另一方面:
/(0?[1-9]|1[012])/
Run Code Online (Sandbox Code Playgroud)
搜索可选的0 1到9,或1搜索后跟0,1或2.所以"13"在这里匹配,因为它包含1,匹配正则表达式的前半部分.要使正则表达式按预期工作,
/^(0?[1-9]|1[012])$/
Run Code Online (Sandbox Code Playgroud)
在^
与$
锚定搜索字符串的开始和结束,分别.
给你提示 - 月份数字“120”在你的版本中也匹配:-)
改变:
my $month = "(0[1-9]|1[012])";
Run Code Online (Sandbox Code Playgroud)
到
my $month = /^(0[1-9]|1[012])$/;
Run Code Online (Sandbox Code Playgroud)
然后玩更多