Perl语言入门笔记:第六天
时间:2010-08-18 来源:linscora
reverse 操作符:
reverse 操作符会读取列表的值(可能来自数组),并接相反的次序返回该列表。假如你对范围操 作符(即..)只能递增计数感到失望,可以这样弥补: @fred = 6..10;
@barney = reverse (@fred); #得 10,9,8,7,6
@wilma = reverse 6..10; #同上,但不需要额外的数组
@fred = reverse @fred; #将逆序后的结果放回原来那个数组 值得注意的是,最后一行用了两次@fred。Perl总是会先计算(符号的右边)要赋的值,再实际进行赋 值的操作。 reverse返回次序相反的列表,但它并不会修改传进来的参数。
reverse @fred; #错误:这不会修改@fred
@fred = reverse @fred; #这才好 sort操作符会读取列表的值(可能来数组),而且会根据内部的字符编码的顺序,对它们进行排序 。
也可以自定义规则来进行排序。 @rocks = qw/ bedrock slate ruble granite/;
@sorted = sort(@rocks); #得到 bderock, granite, rubble, slate
@rocks = sort @rocks; #将排序后的结果存回至@rocks
@numbers = sort 97..102; #得100, 101,102,97,98,99
sort @rocks; #错误,这么做不会修改@rocks
@rocks = sort @rocks; #现在收集来的石头排得井井有条 标量上下文与列表上下文:
所谓上下文,指的是表达式所在的位置。在Perl解析表达式的时候,要么希望得到一个标量,要么 希望得到一个标量,要么希望得到一个列表。表达式所在的位置,Perl期望得到什么,那就是该表 达式的上下文。 42 + something #这里的something必须是标量
sort something #这里的something必须是列表 @people = qw(fred barney betty);
@sorted = sort @people; #列表上下文:barney, betty, fred
$number = 42 + @people; #标量上下文:42 + 3,得45 即使是普通的赋值运算(对标量或列表赋值),都可以有不同的上下文:
@list = @people; #得到三个人的名单列表
$n = @people; #得到人数3 但请不要立刻得出结论经,认为标量上下文中,一定会得到(列表上下文中返回的列表的)元素个 数。大部分能产生表达式,在标量上下文中的返回值,可能要比元素个数更有意义。 sort在标量上下文部是返回undef。 在列表上下文中,它很自然地返回逆序后的列表;在标量上下文中,刚返回逆序后的字符串(先将 列表中所有字符串全部连接在一起,再对结果进行反序处理): @backwards = reverse qw/ yabba dabba doo/;
#会变成 doo, dabba, yabba
$backwards = reverse qw/ yabba dabba doo/;
#会变成oodabbadabbay $fred = something; #标量上下文
@peoples = something; #列表上下文
($wilma, $betty) = something; #列表上下文
($dino) = something; #还是列表上下文 在列表上下文中使用产生标量的表达式:
如果表达式求值结果为标量值,则自动产生一个仅含此标量的列表:
@fred = 6 * 7; #得到仅有单个元素的列表(42)
@barney = "hello" . ' ' . "world";
其实这里有个小小的陷阱:
@wilma = undef; #糟糕!结果是得到一个列表,而且仅有的一个元素为未定义(undef)
#这和下面的做法效果完全不同
@betty = ( ); #这才是正确的清空数组的方法 因为undef是标量值,所以将undef赋值给数组并不会清空数组。要清空的话,直接赋值一个空列表 就可以了。 强制指定标题上下文: 偶尔在列表上下文的地方,你想要强制引入标量上下文,这可以使用伪函数scalar。
这不是真正的函数,只不过告诉Perl这里要切换到标量上下文:
@rocks = qw( talc quartz jade obsidian );
print "How many rocks do you have?\n";
print "I have ", @rocks, "rocks!\n"; #错误,这会输出各种石头的名称
print "I have ", scalar @rocks, "rocks!\n"; #对了,打印出来的是石头种数。 列表上下文中的<STDIN>:
我们之前看过的<STDIN>操作符,在列表上下文中会返回不同的值。
<STDIN>在标量上下文中会返回输入数据的下一行;在列表上下文中,则会返回所有的剩下的行,直 到文件结尾为止。返回的每一行都会成为列表中的某个元素。举例来说:
@lines = <STDIN>; #在列表上下文中读取标准输入
当输入数据来自某个文件时,它会读取文件的剩余部分。但是如果输入数据的来源是键盘,应该如 何表达文件结尾呢?对Unix或类似的系统(包括Linux和Mac OS X)来说,通常可以键入Control-D来 告知系统。不会再有任何输入,即使这个特殊字符会被打印在屏幕上。Perl也不会看到它。对 DOS/Windows系统来说,就要用Control-Z了。 @lines = <STDIN>; #读入所有行
chomp(@lines); #去掉所有的换行符 chomp(@lines = <STDIN>); #上面的整合 习题:
#!/usr/bin/perl -w
print "Enter some lines, then press Ctrl-D:\n"; #或者Ctrl-Z
@lines = <STDIN>;
@out = reverse (@lines);
print @out; ---------------------------------------------
print "Enter some lines, then press Ctrl-D:\n";
print reverse <STDIN>; ====================================== @names = qw/ fred betty barney dino wilma pebbles bamm-bamm/;
print "Enter some numbers from 1 to 7, one per line, then press Ctrl-D:\n";
chomp(@numbers = <STDIN>);
foreach (@numbers) {
print "$names [ $_ - 1]\n";
} 也可以在@names 这个数组中加一个空值。
像这样:因为数组是从0开始的。
@names = qw/ dummy_item fred betty barney dino wilma pebbles bamm-bamm/; ============================================= chomp(@lines = <STDIN>);
@sorted = sort @lines;
print "@sorted\n";
或者让每行分开显示的做法:
print sort <STDIN>; 14:38 2010-8-18
reverse 操作符会读取列表的值(可能来自数组),并接相反的次序返回该列表。假如你对范围操 作符(即..)只能递增计数感到失望,可以这样弥补: @fred = 6..10;
@barney = reverse (@fred); #得 10,9,8,7,6
@wilma = reverse 6..10; #同上,但不需要额外的数组
@fred = reverse @fred; #将逆序后的结果放回原来那个数组 值得注意的是,最后一行用了两次@fred。Perl总是会先计算(符号的右边)要赋的值,再实际进行赋 值的操作。 reverse返回次序相反的列表,但它并不会修改传进来的参数。
reverse @fred; #错误:这不会修改@fred
@fred = reverse @fred; #这才好 sort操作符会读取列表的值(可能来数组),而且会根据内部的字符编码的顺序,对它们进行排序 。
也可以自定义规则来进行排序。 @rocks = qw/ bedrock slate ruble granite/;
@sorted = sort(@rocks); #得到 bderock, granite, rubble, slate
@rocks = sort @rocks; #将排序后的结果存回至@rocks
@numbers = sort 97..102; #得100, 101,102,97,98,99
sort @rocks; #错误,这么做不会修改@rocks
@rocks = sort @rocks; #现在收集来的石头排得井井有条 标量上下文与列表上下文:
所谓上下文,指的是表达式所在的位置。在Perl解析表达式的时候,要么希望得到一个标量,要么 希望得到一个标量,要么希望得到一个列表。表达式所在的位置,Perl期望得到什么,那就是该表 达式的上下文。 42 + something #这里的something必须是标量
sort something #这里的something必须是列表 @people = qw(fred barney betty);
@sorted = sort @people; #列表上下文:barney, betty, fred
$number = 42 + @people; #标量上下文:42 + 3,得45 即使是普通的赋值运算(对标量或列表赋值),都可以有不同的上下文:
@list = @people; #得到三个人的名单列表
$n = @people; #得到人数3 但请不要立刻得出结论经,认为标量上下文中,一定会得到(列表上下文中返回的列表的)元素个 数。大部分能产生表达式,在标量上下文中的返回值,可能要比元素个数更有意义。 sort在标量上下文部是返回undef。 在列表上下文中,它很自然地返回逆序后的列表;在标量上下文中,刚返回逆序后的字符串(先将 列表中所有字符串全部连接在一起,再对结果进行反序处理): @backwards = reverse qw/ yabba dabba doo/;
#会变成 doo, dabba, yabba
$backwards = reverse qw/ yabba dabba doo/;
#会变成oodabbadabbay $fred = something; #标量上下文
@peoples = something; #列表上下文
($wilma, $betty) = something; #列表上下文
($dino) = something; #还是列表上下文 在列表上下文中使用产生标量的表达式:
如果表达式求值结果为标量值,则自动产生一个仅含此标量的列表:
@fred = 6 * 7; #得到仅有单个元素的列表(42)
@barney = "hello" . ' ' . "world";
其实这里有个小小的陷阱:
@wilma = undef; #糟糕!结果是得到一个列表,而且仅有的一个元素为未定义(undef)
#这和下面的做法效果完全不同
@betty = ( ); #这才是正确的清空数组的方法 因为undef是标量值,所以将undef赋值给数组并不会清空数组。要清空的话,直接赋值一个空列表 就可以了。 强制指定标题上下文: 偶尔在列表上下文的地方,你想要强制引入标量上下文,这可以使用伪函数scalar。
这不是真正的函数,只不过告诉Perl这里要切换到标量上下文:
@rocks = qw( talc quartz jade obsidian );
print "How many rocks do you have?\n";
print "I have ", @rocks, "rocks!\n"; #错误,这会输出各种石头的名称
print "I have ", scalar @rocks, "rocks!\n"; #对了,打印出来的是石头种数。 列表上下文中的<STDIN>:
我们之前看过的<STDIN>操作符,在列表上下文中会返回不同的值。
<STDIN>在标量上下文中会返回输入数据的下一行;在列表上下文中,则会返回所有的剩下的行,直 到文件结尾为止。返回的每一行都会成为列表中的某个元素。举例来说:
@lines = <STDIN>; #在列表上下文中读取标准输入
当输入数据来自某个文件时,它会读取文件的剩余部分。但是如果输入数据的来源是键盘,应该如 何表达文件结尾呢?对Unix或类似的系统(包括Linux和Mac OS X)来说,通常可以键入Control-D来 告知系统。不会再有任何输入,即使这个特殊字符会被打印在屏幕上。Perl也不会看到它。对 DOS/Windows系统来说,就要用Control-Z了。 @lines = <STDIN>; #读入所有行
chomp(@lines); #去掉所有的换行符 chomp(@lines = <STDIN>); #上面的整合 习题:
#!/usr/bin/perl -w
print "Enter some lines, then press Ctrl-D:\n"; #或者Ctrl-Z
@lines = <STDIN>;
@out = reverse (@lines);
print @out; ---------------------------------------------
print "Enter some lines, then press Ctrl-D:\n";
print reverse <STDIN>; ====================================== @names = qw/ fred betty barney dino wilma pebbles bamm-bamm/;
print "Enter some numbers from 1 to 7, one per line, then press Ctrl-D:\n";
chomp(@numbers = <STDIN>);
foreach (@numbers) {
print "$names [ $_ - 1]\n";
} 也可以在@names 这个数组中加一个空值。
像这样:因为数组是从0开始的。
@names = qw/ dummy_item fred betty barney dino wilma pebbles bamm-bamm/; ============================================= chomp(@lines = <STDIN>);
@sorted = sort @lines;
print "@sorted\n";
或者让每行分开显示的做法:
print sort <STDIN>; 14:38 2010-8-18
相关阅读 更多 +
排行榜 更多 +