perl 启用“#use 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 脚本因这些警告而关闭(尤其是因为无论如何都有效)?
I am trying to complete a college assignment in Perl, and we've been told by our professor to use:
use strict;
use warnings;
With use strict;
my code works perfectly. with use warnings;
, however, my code spews all this stuff to SDOUT and I don't know why (or how to shut it up). My relevant code is:
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 == ""));
}
With warnings, it spits this out in the middle of my output:
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.
...and it's messing up my formatting (I am generating a table in the console). I tried 'declaring' the scalars, but then (of course) those were in error. How can I get my Perl script to shut up with these warnings (especially since the works anyway)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
首先,学习 Perl 时,您应该始终使用警告并使用严格。
当您执行正则表达式匹配时,您正在匹配字符串中的子字符串,因此您的匹配项是字符串。然而,如果上下文需要,perl 会将字符串转换为数字。例如,如果您编写:
$4 - $1
$4 和 $1 必须是数字,因为字符串没有 - 运算符,因此 Perl 将字符串 $4 和 $1 转换为它们的数字等价物,然后 Perl 执行减法。类似地,如果你写:
$4 == ""
== 运算符只对数字进行操作,因此 Perl 将 $4 转换为数字——但 Perl 犹豫是否将 "" 转换为数字。如果您在需要数字的代码中编写了像“dog”或“”这样的字符串文字,那么 Perl 会怀疑您可能犯了错误,并使用警告告诉 Perl 提醒您可能的错误——而不仅仅是盲目地进行转换。
要在 Perl 中比较字符串,可以使用 eq 运算符。
First, when learning perl you should always use warnings and use strict.
When you perform a regex match, you are matching substrings within strings, so your matches are strings. However, perl will convert strings to numbers if the context calls for that. For instance, if you write:
$4 - $1
$4 and $1 have to be numbers because there is no - operator for strings, so perl converts the strings $4 and $1 to their numeric equivalents, and then perl performs the subtraction. Similarly, if you write:
$4 == ""
the == operator only operates on numbers, so perl converts $4 to a number---but perl is hesitant to convert "" to a number. If you write a string literal like "dog" or "" in your code where a number is called for, then perl suspects you might have made an error, and use warnings tells perl to alert you to the possible error--instead of just blindly doing the conversion.
To compare strings in perl, you use the eq operator.
如果是的话,它只是偶然起作用。正则表达式捕获的是
$1
((\d+)
) 是第一个数字$2
(((,){1}(\d+))
) 是您相当详细地捕获的逗号($3
) 已关注另一个号码 ($4
)。如果不匹配,这将是未定义的(,){1}
)是逗号,则该值未定义。你这样做的目的是什么?(,)
捕获逗号,{1}
重复一次(这是一个无操作)。如果$2
不匹配,则这将是未定义的。$4
((\d+)
) 是紧跟在逗号后面的数字。如果$2
不匹配,则这将是未定义的。$5
(([adc])
) 捕获a
、d
或之一c
.$6
((\d+)
) 捕获另一个数字。$7
到$9
重复$2
到$4
,包括如果$7 则所有这些都未定义
无法匹配。您尝试匹配的数据是什么样的?
除了上述内容之外,当您实际上不需要某些东西时,使用非捕获组(
(?:...)
)通常很有帮助,这样捕获变量更加一致(有还有一些小的性能和内存改进)。在这种情况下,我猜上面的$2
和$7
不需要被捕获......尽管这将取决于当前毫无意义的$3
和$8
实际上应该是。It's only working, if it is, by accident. What that regex captures is
$1
((\d+)
) is the first number$2
(((,){1}(\d+))
) is your rather verbosely captured comma ($3
) followed by another number ($4
). This will be undefined if it doesn't match$3
((,){1}
) is a comma. What did you intend with this?(,)
captures a comma, and{1}
repeats that once (which is a no-op). If$2
doesn't match then this will be undefined.$4
((\d+)
) is the number immediately following the comma. If$2
doesn't match then this will be undefined.$5
(([adc])
) captures one ofa
,d
, orc
.$6
((\d+)
) captures another number.$7
through$9
repeat$2
through$4
, including all of them being undefined if$7
fails to match.What does the data you're trying to match against look like?
Aside from the above, it's often helpful to use non-capturing groups (
(?:...)
) when you don't actually need something, so that the capture variables are more consistent (there are also some minor performance and memory improvements). In this case, I'd guess that$2
and$7
above don't need to be captures... although this will depend on what the currently pointless$3
and$8
are supposed to actually be.这将转到 STDERR,而不是 STDOUT。
捕获变量并不总是被设置;如果不是,它们将是未定义的。例如,您的正则表达式具有
((,){1}(\d+))?
(其中(\d+)
是第四个捕获)。?
使整个组可选。如果不使用它来匹配字符串,$3 和 $4 将保持未定义。在您测试的地方
除非$4 == ""
,否则您应该测试如果定义了$4
。其他一些注意事项:
{1}
不执行任何操作;它表示正则表达式的前面部分应该恰好匹配一次 - 即使没有{1}
也能做到这一点。如果您对不需要捕获的分组使用非捕获组 ((?: ... )
),则可以更轻松地跟踪正在使用的捕获变量。That goes to STDERR, not STDOUT.
Capture variables aren't always set; if they aren't, they will be undefined. For example, your regex has
((,){1}(\d+))?
(where the(\d+)
is the 4th capture). The?
makes the whole group optional. If it is not used in matching the string, $3 and $4 will be left undefined.Where you are testing
unless $4 == ""
you should be testingif defined $4
.A couple other notes:
{1}
does nothing; it says that the preceding part of the regular expression should match exactly once - which it would do without the{1}
too. It can be easier to keep track of which capture variables you are using if you use non-capturing groups ((?: ... )
) for the groupings you don't need captured.