我正在尝试自学Perl,我到处寻找可能是一个非常简单的问题的答案。我已经定义了一个子程序,我调用它来计算单词中的字母数。如果我这样写出来:
$sentence="This is a short sentence.";
@words = split(/\s+/, $sentence);
foreach $element (@words) {
$lngths .= length($element) . "\n";
}
print "$lngths\n";
然后它就像一个魅力。但是,如果我将其包装到子例程中,则拆分不会拆分输入,而是将整个句子计为单个输入。这是我如何定义子程序:
sub countWords {
@words = split(/\s+/, @_);
foreach $element(@words) {
$lngths .= length($element) . "\n";
}
return $lngths;
}
从我阅读的所有页面和我所咨询过的文本中,这应该有效,但事实并非如此。
提前致谢!
答案 0 :(得分:13)
问题在于您使用@_
。这是一个数组,但你像标量一样访问它。
@_
包含此函数的所有参数。它看起来的方式,你传递一个句子,你想分开它。以下是一些可能的方法:
@words = split(/\s+/, $_[0]);
表示“将第一个参数带入函数并将其拆分”。
或者:
my $sentence = shift;
@words = split(/\s+/, $sentence);
几乎相同,但使用中间变量来提高可读性。
事实上,你所做的是:
@words = split(/\s+/, @_);
这意味着:
@_
解释为标量,表示@_
中的数字元素(在本例中为1)"1"
返回数组:
@words = ("1");
答案 1 :(得分:3)
你得到了内森的答案的主要部分;剩下的观察是大多数人不把标点符号和数字都算作字母,但你的子程序呢。我可能会选择:
sub countLetters
{
my($sentence) = @_;
$sentence =~ s/[^[:alpha:]]//gm;
return length($sentence);
}
这里的关键点是my
子句中变量列表周围的括号。通常,您有几个参数传递给sub,您可以将它们分配(副本)到子例程中的变量,如下所示:
my($var1, $var2, $var3) = @_;
括号提供“列表上下文”并确保将@_
的第一个元素复制到$var1
,将第二个元素复制到$var2
,依此类推。没有括号,您有'标量上下文',并且在标量上下文中计算数组时,返回的值是数组中元素的数量。因此:
my $var1, $var2, $var3 = @_;
可能会将3分配给$var1
(因为有三个值传递给子例程),$var1
和$var2
都是undef
。
正则表达式删除字符串中的所有非字母字符;字母数是剩下的长度。
答案 2 :(得分:0)
在计算字符时,perl的音译操作符通常会派上用场。 要计算非空白字符而不必将字符串拆分为单独的单词,您可以执行以下操作:
$lngths = $sentence =~ tr/ \t\f\r\n//c;