我有关于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行的regexp编译中使用未初始化的值$ pattern。
但是当我使用:&mysplit("a:b:c", qr/:/);
时,没关系
那么,我想知道qr//
和m//
之间的区别是什么?
为什么$_
与此相关?
为什么在split /:/, "a:b:c";
的案例中没问题呢?
提前谢谢!
答案 0 :(得分: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.
如果传递了空字符串,则错误的这一部分将是静默的。
此外,您应该知道在子程序调用前使用&符号&
具有特定功能。除非您打算使用该功能,否则不应使用它。调用sub的各种方法都是这些,如perldoc perlsub:
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(...)
答案 1 :(得分:0)
此错误:
Use of uninitialized value $pattern in regexp compilation at ./test.pl line 7.
是因为你没有引用第二个参数
&mysplit("a:b:c", /:/);
如果您尝试在$pattern
中打印sub mysplit
,您会看到它是一个空字符串。