Perl-列表和数组2

本文介绍了Perl编程中字符串内插的语法,包括数组内插和特殊字符转义,以及如何避免歧义。还详细讲解了foreach循环用于遍历数组的用法,强调了循环变量与数组元素的关系。此外,讨论了Perl中的默认变量$_,以及reverse和sort操作符的功能和使用。最后,提到了上下文的概念,包括标量上下文和列表上下文的影响,以及如何在不同上下文中正确使用表达式。
摘要由CSDN通过智能技术生成

1. 字符串中的数组内插

和标量一样,数组的内容同样可以被内插到双引号引起的字符串中
内插时,会在数组的各个元素之间自动添加分隔用的空格

@rocks = qw{ flitstone slate rubble };
print "quartz @rocks limestone\n";

数组被内插后,首尾都不会增加额外的空格

print "There rocks are: @rocks.\n";
print "There's nothing in the parens (@empty) here.\n";

如何把电子邮件放在双引号内

$email = "fred@bedrock.edu"; # 错!这样会内插@bedrock这个数组
$email = "fred\@bedrock.edu"; # 对@进行转义操作
$email = 'fred@bedrock.edu'; # 直接用单引号来定义字符串

内插数组中的某个元素时,会被替换成该元素的值

@fred = qw(hello dolly);
$y = 2;
$x = "This is $fred[1]'s place"; # This is dolly's place
$x = "This is $fred[$y-1]'s place"; # This is dolly's place

注意索引表达式会被当成普通字符串表达式处理

如果要在某个标量变量后面接着写左方括号,需要首先将这个方括号隔开,它才不至于被识别为数组引用的一部分

@fred = qw(eating rocks is wrong);
$fred = "right"; # 我们想说this is right[3]
print "this is $fred[3]\n"; # 用到了$fred[3],打印"wrong"
print "this is ${fred}[3]\n"; # 打印"right" (用花括号避开歧义)
print "this is $fred"."[3]\n"; # 还是打印right (用分开的字符串)
print "this is $fred\[3]\n";  # 还是打印right (用反斜线避开歧义)

2. foreach控制结构

处理整个数组或列表内的数据,foreach循环能逐项遍历列表中的值,依次提取使用

foreach $rock (qw/ bedrock slate lava/){
	print "One rock is $rock.\n"; # 依次打印所有2种石头的名称
}

每次循环迭代时,控制变量都会从列表中取得新值
控制变量不是列表元素的copy,它就是列表元素本身,假如在循环中修改了控制变量的值,也就同时修改了这个列表元素

@rock = qw/ bedrock slate lava /;
foreach $rock(@rocks){
	$rock = "\t$rock"; # 在@rocks的每个元素前加上制表符
	$rock .= "\n"; # 同时在末尾加上换行符
}
print "The rocks are:\n", @rocks; # 各自占一行,并使用缩排

当循环结束时,循环变量仍是循环执行前的值,如果循环变量在循环嵌未被赋值,则为undef

$rock = 'shale';
@rock = qw/ bedrock slate lava /;

foreach $rock (@rocks){
	...
}
print "rock is still $rock\n"; # 打印 'rock is still shale'

代码块中的...为占位符,又叫yada yada操作符

3. Perl最喜欢的默认变量 $_

假如在foreach循环开头省略控制变量,perl就会使用默认变量$_

foreach (1..10){
	print "I can count to $_!\n";
}

$_ = "Yabba dabba doo\n";
print; # 默认打印$_

4. reverse操作符

reverse操作符会读取列表的值(一般来自数组),并按相反次序返回新的列表

@fred = 6..10;
@barney = reverse(@fred);  # 返回 10,9,8,7,6
@wilma = reverse 6..10; # 同上,但无需额外的数组
@fred = reverse @fred; # 倒序后保存到原来的数组

perl总是在赋值前先计算等号右边的表达式
reverse只是返回倒序后的列表,不会修改给它的参数

reverse @fred; # 错误用法
@fred = reverse @fred; # 正确用法

5. sort操作符

读取列表的值,依次按字符的内部编码顺序对它们进行排序
对字符串而言,就是字符在计算机内部表示的代码点
大写字符排在小写字符前面,数字排在字母之前,而标点符号则散落各处

@rocks= qw/ bedrock slate rubble granite /;
@sorted = sort(@rocks); # 返回 bedrock, granite, rubble, slate
@back = reverse sort @rocks; # 逆序,返回 slate, rubble, granite, bedrock
@rocks = sort @rocks;
@numbers = sort 97..102; # 得到 100, 101, 102, 97, 98, 99

sort操作符将数字当成字符串来排序
按默认的排序规则,任何以1开头的字符串都会被排在以9开头的字符串之前,此外,排序操作符和reverse操作符一样,不会修改原始参数,只是返回新的列表

sort @rocks; # 错误
@rocks = sort @rocks; #正确

6. each操作符

对数组和哈希使用each操作符

每次对数组调用each,会返回数组种下一个元素对应的2个值

  1. 数组索引
  2. 数组元素
require v5.12;

@rocks = qw/ bedrock slate rubble granite /;
while( ($index, $value ) = each @rocks ){
	print "$index:$value\n";
}

如果不使用each,就得自己根据索引从小到大依次遍历,然后借助索引取得元素值

@rocks = qw/ bedrock slate rubble granite /;
foreach $index (0..$#rocks){
	print "$index: $rocks[$index]\n";
}

7. 标量上下文和列表上下文

同一表达式出现在不同的地方时会有不同的意义
操作值按照数字进行操作时就是数字结果,而按照字符串进行操作时返回的则是字符串结果,其中起到决定性因素的是操作符,而不是被操作的各种变量或直接量

@people = qw( fred barney betty );
@sorted = sort @people; # 列表上下文: barney, betty, fred
$number = 42 + @people; # 标量上下文: 42 + 3 = 45

@list = @people # 得到3
$n = @people;

任何表达式都可以产生列表或标量,根据上下文而定

8. 在标量上下文中使用产生列表的表达式

@backwards = reverse qw/ yabba dadda doo /; # 会得到 doo, dabba, doo
$backwards = reverse qw/ yabba dadda doo /; # 会得到 oodabbadabbay
$fred = something; # 标量上下文
@pebbles = something; # 列表上下文
($wilma, $betty) = something; # 列表上下文
($dino) = something; # 还是列表上下文

如果是给列表赋值(不管其中元素的个数),那就是列表上下文
如果是给数组赋值,那还是列表上下文

标量上下文的例子

$fred = something;
$fred[3] = something;
123 + something
something + 654
if (something) {...}
while (something) {...}
$fred[something] = something;

列表上下文的例子

@fred = something;
($fred, $barney) = something;
($fred) = something;
push @fred, something;
foreach $fred (something) {...}
sort something
reverse something
print something

9. 在列表上下文中使用产生标量的表达式

@fred = 6 * 7; # 得到仅有单个元素的列表(42)
@barney = "hello" . ' ' . "world";

@wilma = undef; # 得到的是单个元素的列表,元素值为未定义的(undef)
@betty = (); # 清空数组的正确方法

10. 强制指定标量上下文

有时在列表上下文的地方需要引入标量上下文,可以使用伪函数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"; # 正确,打印出来的是石头种数

11. 列表上下文中的<STDIN>

在标量上下文中,<STDIN>返回的是输入数据的下一行内容
在列表上下文中,<STDIN>返回则是所有剩下行的内容,1行1个元素,直到文件结尾

@line = <STDIN>; # 在列表上下文中读取标准输入

当输入数据来自某个文件时,它会读取文件的剩余部分。
但如果输入数据的来源是键盘, 键入Ctrl + D(Ctrl + Z)来告知系统,不会再有任何输入了

如果运行程序的人在键入三行数据,通过对应按键告知系统输入完毕(到达文件末尾),最后得到的数组就会包含三个元素,每个元素都是一个以换行符结尾的字符串,因为这些换行符也是输入的内容

@line = <STDIN>; # 一次读取所有行的内容
chomp(@lines); # 然后再去掉换行符

chomp(@lines = <STDIN>); # 一次读入所有行,换行符除外
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值