1

我正在尝试在 .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'(无英寸)
  4. 4' 6'' x 7' (无英寸和英寸的组合)

我收到的警告是:

在 script.pl 第 47 行、第 567 行使用未初始化值 $6 以及 (+)。

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

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

4

3 回答 3

12

您可以使用defined功能:

my $height;
if(defined($6))
{
    $height = $4*12+$6;
}
else
{
    $height = $4*12;
}
于 2013-07-18T15:28:18.497 回答
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(or $4) 为假(undef、零或空字符串)而不是 undef 时使用零,但这在这里完全没问题。

于 2013-07-18T16:05:32.977 回答
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)。

如果您要使用该||技术,请确保将左侧和右侧放在括号内,以避免运算符优先级的副作用。

于 2013-07-18T16:09:01.453 回答