4

我对 Perl qr运算符有疑问:

#!/usr/bin/perl -w
&mysplit("a:b:c", /:/);  
sub mysplit {  
    my($str, $pattern) = @_;  
    my @arr = split $pattern, $str;  
    print "@arr\n";  
}

结果是:

在 ./test.pl 第 3 行的模式匹配 (m//) 中使用未初始化的值 $_。
在 ./test.pl 第 7 行的正则表达式编译中使用未初始化的值 $pattern。

但是当我使用时:&mysplit("a:b:c", qr/:/);,没关系。所以,我想知道和
有什么区别? 为什么在这里相关? 为什么在这种情况下可以? qr//m//
$_
split /:/, "a:b:c";

先感谢您!

4

2 回答 2

11

好吧,你的问题是这个表达式:

/:/

真正的意思是:

$_ =~ /:/

这就是为什么 perl 在$_.

qr()运算符没有这个快捷方式,这就是为什么在这种情况下它本身是一个可接受的语句。

因此,要明确:您的陈述:

&mysplit("a:b:c", /:/);

真正的意思是:

&mysplit("a:b:c", $_ =~ /:/);

由于$_未定义,正则表达式匹配返回空列表。它本可以返回空字符串,但由于您有列表上下文,它返回空列表,使错误更加明显。

因为它返回空列表,所以只有一个参数传递给mysplit(),这就是您收到第二个警告的原因:

Use of uninitialized value $pattern in regexp compilation at ./test.pl line 7.

如果传递了空字符串,则这部分错误将保持沉默。

此外,您应该知道&在子例程调用前使用 & 符号具有特定的功能。除非您打算使用该功能,否则不应使用它。如perldoc perlsub中所述,调用 sub 的各种方法如下:

NAME(LIST);  # & is optional with parentheses.
NAME LIST;   # Parentheses optional if predeclared/imported.
&NAME(LIST); # Circumvent prototypes.
&NAME;       # Makes current @_ visible to called subroutine.

在您的情况下,默认方式是最上面的方式:mysplit(...)

于 2013-05-30T09:02:48.787 回答
0

这个错误:

Use of uninitialized value $pattern in regexp compilation at ./test.pl line 7.

是因为你没有引用第二个参数

&mysplit("a:b:c", /:/);

如果您尝试打印$patternsub mysplit您会看到它是一个空字符串。

于 2013-05-30T09:10:00.787 回答