perl带有`#use warnings;`的正则表达式标量变量

时间:2011-07-15 02:15:47

标签: regex perl warnings

我正在尝试在Perl完成大学任务,我们的教授告诉我们使用:

use strict;
use warnings;

使用use strict;我的代码完美无缺。然而,使用use warnings;,我的代码将所有这些东西吐到SDOUT,我不知道为什么(或者如何关闭它)。我的相关代码是:

while($diff =~ /^(\d+)((,){1}(\d+))?([adc])(\d+)((,){1}(\d+))?/mgi) {
    # This line is used for debugging the $diff regular expression scalars.
    # print "\n1: $1\t2: $2\t 3: $3\t4: $4\t5: $5\t6: $6\t7: $7\t8: $8\t9: $9\n";

    $difflinestotal += ($4 - $1) unless $4 == "";
    $difflinestotal += ($9 - $6) unless $9 == "";
    $difflinestotal += 1 if (($4 == "") && ($9 == ""));
}

有警告,它会在输出中间吐出:

Argument "" isn't numeric in numeric eq (==) at ./partc.pl line 145.
Use of uninitialized value $4 in numeric eq (==) at ./partc.pl line 145.
Argument "" isn't numeric in numeric eq (==) at ./partc.pl line 146.
Argument "" isn't numeric in numeric eq (==) at ./partc.pl line 147.
Use of uninitialized value $4 in numeric eq (==) at ./partc.pl line 147.
Argument "" isn't numeric in numeric eq (==) at ./partc.pl line 147.
Use of uninitialized value $9 in numeric eq (==) at ./partc.pl line 146.
Use of uninitialized value $4 in numeric eq (==) at ./partc.pl line 145.
Use of uninitialized value $9 in numeric eq (==) at ./partc.pl line 146.
Use of uninitialized value $4 in numeric eq (==) at ./partc.pl line 147.
Use of uninitialized value $9 in numeric eq (==) at ./partc.pl line 147.
Use of uninitialized value $4 in numeric eq (==) at ./partc.pl line 145.
Use of uninitialized value $4 in numeric eq (==) at ./partc.pl line 147.

......它搞乱了我的格式化(我在控制台中生成一个表)。我试图“宣布”标量,但当然(当然)那些是错误的。如何让我的Perl脚本关闭这些警告(特别是因为无论如何)?

3 个答案:

答案 0 :(得分:6)

这是STDERR,而不是STDOUT。

并不总是设置捕获变量;如果他们不是,他们将是不确定的。例如,你的正则表达式有((,){1}(\d+))?(其中(\d+)是第4次捕获)。 ?使整个组可选。如果它不用于匹配字符串,则$ 3和$ 4将保持未定义。

您正在测试unless $4 == "",您应该测试if defined $4

其他一些注释:{1}什么都不做;它说正则表达式的前一部分应该只匹配一次 - 它也可以没有{1}。如果您使用非捕获组((?: ... ))进行不需要捕获的分组,则可以更容易地跟踪您正在使用的捕获变量。

答案 1 :(得分:2)

这只是偶然的,如果是的话。正则表达式捕获的是

  • $1(\d+))是第一个数字

  • $2((,){1}(\d+)))是您相当详细地捕获的逗号($3),后跟另一个数字($4)。如果不匹配

  • ,这将是未定义的
  • $3(,){1})是一个逗号。你有什么打算这个? (,)捕获一个逗号,{1}重复一次(这是一个无操作)。如果$2不匹配,那么这将是未定义的。

  • $4(\d+))是紧跟逗号后面的数字。如果$2不匹配,那么这将是未定义的。

  • $5([adc]))会抓取adc中的一个。

  • $6(\d+))会抓住另一个号码。

  • $7$9重复$2$4,包括$7无法匹配时所有这些都未定义。

您尝试匹配的数据是什么样的?

除了上述内容之外,当您实际上不需要某些内容时,使用非捕获组((?:...))通常很有帮助,因此捕获变量更加一致(还有一些较小的性能和内存)改进)。在这种情况下,我猜上面的$2$7不需要捕获......虽然这取决于当前无意义的$3和{{1}应该是真的。

答案 2 :(得分:0)

首先,在学习perl时,你应该总是使用警告并使用strict。

执行正则表达式匹配时,您匹配字符串中的子字符串,因此您的匹配项是字符串。但是,如果上下文要求,perl会将字符串转换为数字。例如,如果你写:

$ 4 - $ 1

$ 4和$ 1必须是数字,因为没有 - 字符串的运算符,所以perl将字符串$ 4和$ 1转换为它们的数字等价物,然后perl执行减法。同样,如果你写:

$ 4 ==“”

==运算符只对数字进行操作,因此perl将$ 4转换为数字---但perl对于将“”转换为数字犹豫不决。如果你在你的代码中写了一个字符串文字,如“dog”或“”,那么perl会怀疑你可能犯了错误,并使用警告告诉perl警告你可能的错误 - 而不仅仅是盲目地进行转换。

要比较perl中的字符串,请使用eq运算符。