146 lines
6.9 KiB
Markdown
146 lines
6.9 KiB
Markdown
|
||
# 字符和数组生成
|
||
|
||
## 50.生成和打印首字母表
|
||
|
||
perl -le 'print a..z'
|
||
|
||
本行代码打印所有从a到z的字母“abcdefghijklmnopqrstuvwxyz”。本例中应用了范围操作符“...”生成字母。当范围操作符用在字符列表上下文的时候,会从左边使用魔力自增算法向前递增一个字符,直到范围右边的字符。于是这行代码通过a..z的范围依次递增从a到z的整个字母表。
|
||
由于使用了裸字符 a和z,如果你开启strict模式,这行代码将会报错。从语法角度,更正确的版本是:
|
||
|
||
perl -le 'print ("a".."z")'
|
||
|
||
记住访问操作符..生成是一个列表值。如果你愿意,你可以打印出他们,之间通过“$,”指定的分割符间隔开来,比如:
|
||
|
||
perl -le '$, = ","; print ("a".."z")'
|
||
|
||
从语法上讲,更好的方法是采用join方法来将列表的元素之间分割。
|
||
|
||
perl -le 'print join ",", ("a".."z")'
|
||
|
||
上面通过join函数吧a..z列表用逗号隔开并打印出了。
|
||
|
||
## 51.生成并打印从“a”到“zz”的所有字串。
|
||
|
||
perl -le 'print ("a".."zz")'
|
||
|
||
本例我们又实用了范围操作符“..”。这次不是终止于“z”而是,更前进一个字符生成“aa”,接着继续往前生成“ab”,“ac”,…,达到 “az”。在这个点上往前到了“ba”,接着继续,直到达到“zz”。
|
||
同样地,你可以生成从“aa”到“zz”的左右字符:
|
||
|
||
perl -le 'print "aa".."zz"'
|
||
|
||
## 52.生成一个16进制查询表。
|
||
|
||
@hex = (0..9, "a".."f")
|
||
|
||
此处,数组@hex会保存0, 1, 2, 3, 4, 5, 6, 7, 8, 9以及字母a,b,c,d,e,f等值。
|
||
|
||
perl -le '$num = 255; @hex = (0..9, "a".."f"); while ($num) { $s = $hex[($num%16)&15].$s; $num = int $num/16 } print $s'
|
||
|
||
很明显,转化一个数字为16进制的更简单的方法是用%x格式符的printf函数(或者sprintf函数)。(上例演示了使用我们用访问操作符生成的16进制查询表)。
|
||
|
||
perl -le '$hex = sprintf("%x", 255); print $hex'
|
||
|
||
## 53.把16进制数字转换回10进制,使用hex函数:
|
||
|
||
perl -le '$num = "ff"; print hex $num'
|
||
|
||
hex函数输入一个10进制字符(可以是“0x”开头或者不是),并把它转化为10进制。
|
||
|
||
## 53.生成一个8字符的随机密码。
|
||
|
||
perl -le 'print map { ("a".."z")[rand 26] } 1..8'
|
||
|
||
此处,map函数执行("a".."z")[rand 26]代码8次(由于要在虚拟的范围1..8循环)。每一次循环代码会从字母表中随机选出一个字母。当map执行完循环,返回生成的字符列表,并连接在一起打印出来。
|
||
如果和你还希望在密码中包含数字,可以把0..9增加到字符列表,并且选择范围从26变为36,因为有36个不同的字符以供选择:
|
||
|
||
perl -le 'print map { ("a".."z", 0..9)[rand 36] } 1..8'
|
||
|
||
如果你需要更长的密码,可以把1..8变为1..20生成一个20个字符串的长密码。
|
||
|
||
## 54.生成一个特定长度的字串。
|
||
|
||
perl -le 'print "a"x50'
|
||
|
||
操作符“X”是重复操作符。本行代码生成一个50个字符“a”组成的自串,并打印出来。
|
||
如果重复操作符用于列表上下文,他将生成由所给元素重复次数的一个列表(而不是标量)。
|
||
|
||
perl -le '@list = (1,2)x20; print "@list"'
|
||
|
||
本行代码生成一个20次重复(1,2)的列表(看起来像(1,2,1,2,…))。
|
||
|
||
## 55.有一个字符串生成一个数组。
|
||
|
||
@months = split ' ', "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
|
||
|
||
此处@months会保存包含来自于字符串中的月份名称的值。由于每一个月份名又空格隔开,split函数分割开他们并保存在@months数组中。于是$months[0]包含”Jan”, $months[1]包含”Feb”,…, $months[11]包含”Dec”。
|
||
|
||
另外一种方法是使用qw//操作符:
|
||
|
||
@months = qw/Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec/
|
||
|
||
qw//操作符接收一个空格分割的字符,生成一个数组,每一个单词为数组中的一个元素。
|
||
|
||
## 56.由一个数组生成一个字符串。
|
||
|
||
@stuff = ("hello", 0..9, "world"); $string = join '-', @stuff
|
||
|
||
此处,数组@stuff的所有值缩为一个字符串$string,之间用连字符分隔开。把一个数组转化为字符串使用join函数,join函数接收一个分隔符和一个列表,把列表中的所有元素连接为一个字符串,之间用指定分隔符隔开。
|
||
|
||
|
||
## 57.找出字串中字符的区位码
|
||
|
||
perl -le 'print join ", ", map { ord } split //, "hello world"'
|
||
|
||
本行代码引入字符串“hello world”,利用split//,”hello world”把其分割为字符列表,接着用ord函数map每一个字符为8为区位码数字(比如ASCII或者 EBCDIC)。最后所有数字join连接在一起,用逗号隔开,并打印出来。
|
||
另一种实现同样功能的方法是使用unpack函数,指定C*作为unpack模板(C意思是无符号字符,*指所有字符):
|
||
|
||
perl -le 'print join ", ", unpack("C*", "hello world")'
|
||
|
||
## 58.转换ASCII码值列表为一个字串。
|
||
|
||
perl -le '@ascii = (99, 111, 100, 105, 110, 103); print pack("C*", @ascii)'
|
||
|
||
和上例我们看克unpack一个字串为值列表一样,我们也可以反过来他们pack回一个字串。
|
||
另一种方法,是利用chr函数,以码值为参数,返回相对应的字符:
|
||
|
||
perl -le '@ascii = (99, 111, 100, 105, 110, 103); print map { chr } @ascii'
|
||
|
||
和上面$55例相似,利用chr函数的map每一个@ascii的值为字符。
|
||
|
||
## 59.生成1到100所有奇数的数组。
|
||
|
||
perl -le '@odd = grep {$_ % 2 == 1} 1..100; print "@odd"'
|
||
|
||
本行代码生成从1到99的奇数组成的数组(1,3,5,7,9,…,99)。我们使用grep筛选列表1到100的各个元素,筛选代码用的是$_ % 2 ==。只有筛选代码评判为true的元素会返回。在本例中测试是否除2余数为1,如果是,这个数字为奇数,他会加到@odd数组中。
|
||
另外一种方法基于奇数具有低字节位为1的事实,并以此为测试:
|
||
|
||
perl -le '@odd = grep { $_ & 1 } 1..100; print "@odd"'
|
||
|
||
表达式$_ & 1 分离出低字节位出来,并且grep筛选低字节位为1(奇数)。
|
||
关于字节见explanation of bit-hacks。
|
||
|
||
## 60.生成1到100所有偶数的数组
|
||
|
||
perl -le '@even = grep {$_ % 2 == 0} 1..100; print "@even"'
|
||
|
||
本行代码和上例基本上一样,除了grep test条件是偶数(能被2整除)。
|
||
|
||
## 61.计算字串的长度。
|
||
|
||
perl -le 'print length "one-liners are great"'
|
||
|
||
作为结束,length子程序返回字符串的长度。
|
||
|
||
## 62.计算数组元素个数
|
||
|
||
perl -le '@array = ("a".."z"); print scalar @array'
|
||
|
||
在标量上下文评估一个数组(或者哈希)的值会返回数组元素的数量。
|
||
另外一种计算方法是数组最后一个元素下表值加1:
|
||
|
||
perl -le '@array = ("a".."z"); print $#array + 1'
|
||
|
||
此处,$#array返回数组@array的最后一个元素的下标值,由于下标由0开始所以最后一个元素的下标比数组个数小1,所以通过加1就可以获数组的元素个数。
|
||
|