我在尝试解析时尝试修改只读值

时间:2014-08-23 15:47:25

标签: regex perl

我收到错误:尝试修改只读值

#!/usr/bin/perl

$s = '10/25/95';

print "\$s = $s";

($1, $2, $3) = ($s =~ /(\d{1,2})\/(\d{1,2})\/(\d{2,4})/); # getting error here

print "$1 $2 $3 \n";

print 'Done..."

2 个答案:

答案 0 :(得分:6)

您无法分配到$1$2等变量,因为这些变量是只读的。

你想要的是

my $s = '10/25/95';
print "\$s = $s";

print "$1 $2 $3 \n" if $s =~ /(\d{1,2})\/(\d{1,2})\/(\d{2,4})/;

if (my ($x, $y, $z) = $s =~ /(\d{1,2})\/(\d{1,2})\/(\d{2,4})/ ) {

  print "$x $y $z \n";
}

答案 1 :(得分:1)

您似乎对$1$2等的初始化方式存在误解。

请遵守此文档perlretut - Extracting Matches

  

提取匹配

     

分组元字符()还提供另一个完全不同的功能:它们允许提取匹配的字符串部分。这对于找出匹配的和一般的文本处理非常有用。对于每个分组,匹配内部的部分会进入特殊变量$1$2等。它们可以像普通变量一样使用:

       # extract hours, minutes, seconds
       if ($time =~ /(\d\d):(\d\d):(\d\d)/) {    # match hh:mm:ss format
           $hours = $1;
           $minutes = $2;
           $seconds = $3;
       }
     

read more...

如您所见,如果模式匹配,正则表达式引擎会自动初始化捕获组变量。重要的一件事是在尝试使用捕获的变量之前使用if来验证你的正则表达式是否真正匹配。

此外,请确保在每个perl脚本中包含use strict;use warnings;。这是成为更好的Perl程序员的第一件事。

以下是我按照这些修补程序修改脚本的方法:

#!/usr/bin/perl
use strict;
use warnings;

my $s = '10/25/95';

print "\$s = $s\n";

if ($s =~ m{(\d{1,2})/(\d{1,2})/(\d{2,4})}) {
    print "$1 $2 $3 \n";
} else {
    warn "Unable to match pattern";
}

print 'Done...';

输出:

$s = 10/25/95
10 25 95 
Done...