如何检查变量(例如$ 3)是否存在,以便我不会收到有关“未初始化值”的警告?

时间:2013-07-18 15:24:24

标签: regex perl

我正在尝试在.csv文件上运行一个脚本,该脚本将英尺和英寸的大小转换为以英寸为单位的宽度列和以英寸为单位的高度。

不使用严格模式时效果很好,但设置use warnings;时会返回警告消息。

我的问题出现在这里:

if ($data[$index_num] =~ /(\d+)'( (\d+)'')? x (\d+)'( (\d+)'')?/) {

    my $width = $1*12+$3;
    my $height = $4*12+$6;

    ...
}

由于有时大小可能是5'x 8',因此特殊变量$ 3和$ 6不存在。

所有可能的尺寸格式如下:

  1. 5'1''x 6'7''(所有单个数字)
  2. 10'1''x 5'10''(单数字和双数字的组合)
  3. 5'x 8'(No Inches)
  4. 4'6''x 7'(无英寸和英寸的组合)
  5. 我收到的警告是:

      

    在script.pl第47行第567行另外使用未初始化的值$ 6(+)。

    在情况3或4中都会发生这种情况,其中宽度或高度都缺少英寸。

    在尝试使用它们之前,我如何检查是否存在$ 3或$ 6?

3 个答案:

答案 0 :(得分:12)

您可以使用defined功能:

my $height;
if(defined($6))
{
    $height = $4*12+$6;
}
else
{
    $height = $4*12;
}

答案 1 :(得分:10)

首先,让我们摆脱无用的捕获:

/(\d+)'(?: (\d+)'')? x (\d+)'(?: (\d+)'')?/

不匹配的捕获设置为undef,因此您可以使用defined//

my $width  = $1 * 12 + ($2 // 0);
my $height = $3 * 12 + ($4 // 0);
在Perl 5.10中引入了

//。为了向后兼容,您可以使用以下内容:

my $width  = $1 * 12 + ($2 || 0);
my $height = $3 * 12 + ($4 || 0);

$2(或$4)为false(undef,零或空字符串)而不是undef时,第二个版本使用零,但这里完全没问题。

答案 2 :(得分:3)

如果您只是想测试一个数字并且您很乐意在没有匹配时计算结果,那么您可以说:


if ($data[$index_num] =~ /(\d+)\'( (\d+)\'\')? x (\d+)\'( (\d+)\'\')?/) {

    my $width = ( $1 || 0 ) * 12 + ( $3 || 0 );
    my $height = ( $4 || 0 ) * 12 + ( $6 || 0 );

    ...
}

为什么这样做?因为,如果$1未定义,则($1 || 0)会返回右侧,或0。同样,如果$1为零,那么OR条件的左侧也将失败,但仍返回0。如果$1非零且已定义,则会返回左侧($1)。

如果您要使用||技术,请确保将左侧和右侧放在括号内,以避免操作员优先副作用。