Perl正则表达式错误地评估表达式

时间:2018-04-22 19:20:44

标签: regex perl

我有以下perl代码,其中包含一个字符串,我需要针对几种情况进行检查,以便决定如何处理它。他们都没有工作。代码如下所示:

my $param = "02 1999";
my @months = qw(january february march april may june july august september october november december);

my $white = /^\s*$/; #check if all whitespace
my $singleyear = /^\d{2,4}$/; #check if 2-4 digits
my $nummonth = /^\d{1,2}\s\d{1,4}$/; #check if 1-2 digits then 1-4

if ($param =~ $white) {
    my($day, $month, $year)=(localtime)[3,4,5];
    my $monthname = $months[$month]; 
    print "$monthname $year\n";
}
if ($param =~ $singleyear) {
    print "$param\n";
}
if ($param =~ $nummonth) {
    my $monthnumber = $param =~ /^\d{1,2}/; #grabs the number at the front of the string
    my $monthstring = $months[$monthnumber]; 
    my $yearnumber = $param =~ /(\d{1,4})$/; #grab second number, it does this wrong
    print "$monthstring $yearnumber\n";
}

鉴于上述情况,输出应该只是:

february 1999

相反,输出是:

3 118
02 1999
february 1 #this only grabbed the first digit for some reason.

因此,由于某种原因,所有案例都被评为真实,而且这一年的捕获甚至都没有起作用。我究竟做错了什么?在regex101上测试我的所有正则表达式都运行正常,但不在脚本中。

1 个答案:

答案 0 :(得分:3)

我发现两个问题对你的问题至关重要。

首先,您显然希望在变量$white$singleyear$nummonth中保存预编译的正则表达式,但是您没有使用正确的运算符 - 您应该使用{{ 3}}编译并保存正则表达式。像my $white = /^\s*$/;这样的代码将运行针对qr//的正则表达式,并将结果存储在$white中。

其次,my $monthnumber = $param =~ /^\d{1,2}/;有两个问题:在标量上下文中与$_一起使用的=~ operator只返回一个真/假值(1你&{ #39;在输出february 1中重新查看),但是如果你想从正则表达式获取捕获组,你需要在列表上下文中使用它,在这种情况下说my ($monthnumber) = ...(相同)问题适用于$yearnumber)。其次,正则表达式不包含任何捕获组!

我无法准确获得您声明的输出(虽然它已经关闭) - 请查看m//,特别是因为您的帖子最初包含了很多语法错误。如果我应用上面描述的修复,我得到输出

march 1999

这就是我所期望的 - 我希望你能弄明白如何解决这个错误。

更新:我应该补充一点,您也不需要自己尝试解析日期/时间。我最喜欢的日期/时间处理模块是Minimal, Complete, and Verifiable example(以及DateTime),但在这种情况下核心DateTime::Format::Strptime就够了:

use Time::Piece;
my $param = "02 1999";
my $dt = Time::Piece->strptime($param, "%m %Y");
print $dt->fullmonth, " ", $dt->year, "\n";       # prints "February 1999"
相关问题