perl one-liners explained 中文版 (四)字符和数组生成

perl one-liners explained,是继《Famous Awk One-Liners Explained》和《Famous Sed One-Liners Explained》,后Peteris Krumin推出的又一个系列文章,并已经出书了。本blog会陆续对其进行翻译成中文,以便大家学习。本篇是第四部分——数组和字符生成

原文地址:http://www.catonmat.net/download/perl1line.txt

原书blog地址:http://www.catonmat.net/blog/perl-book/

本翻译项目地址:https://github.com/bollwarm/perlonelinecn

字符和数组生成

50.生成和打印首字母表

本行代码打印所有从a到z的字母“abcdefghijklmnopqrstuvwxyz”。本例中应用了范围操作符“…”生成字母。当范围操作符用在字符列表上下文的时候,会从左边使用魔力自增算法向前递增一个字符,直到范围右边的字符。于是这行代码通过a..z的范围依次递增从a到z的整个字母表。 由于使用了裸字符 a和z,如果你开启strict模式,这行代码将会报错。从语法角度,更正确的版本是:

记住访问操作符..生成是一个列表值。如果你愿意,你可以打印出他们,之间通过“$,”指定的分割符间隔开来,比如:

从语法上讲,更好的方法是采用join方法来将列表的元素之间分割。

上面通过join函数吧a..z列表用逗号隔开并打印出了。

51.生成并打印从“a”到“zz”的所有字串。

本例我们又实用了范围操作符“..”。这次不是终止于“z”而是,更前进一个字符生成“aa”,接着继续往前生成“ab”,“ac”,…,达到 “az”。在这个点上往前到了“ba”,接着继续,直到达到“zz”。 同样地,你可以生成从“aa”到“zz”的左右字符:

52.生成一个16进制查询表。

此处,数组@hex会保存0, 1, 2, 3, 4, 5, 6, 7, 8, 9以及字母a,b,c,d,e,f等值。

很明显,转化一个数字为16进制的更简单的方法是用%x格式符的printf函数(或者sprintf函数)。(上例演示了使用我们用访问操作符生成的16进制查询表)。

53.把16进制数字转换回10进制,使用hex函数:

hex函数输入一个10进制字符(可以是“0x”开头或者不是),并把它转化为10进制。

53.生成一个8字符的随机密码。

此处,map函数执行(“a”..”z”)[rand 26]代码8次(由于要在虚拟的范围1..8循环)。每一次循环代码会从字母表中随机选出一个字母。当map执行完循环,返回生成的字符列表,并连接在一起打印出来。 如果和你还希望在密码中包含数字,可以把0..9增加到字符列表,并且选择范围从26变为36,因为有36个不同的字符以供选择:

如果你需要更长的密码,可以把1..8变为1..20生成一个20个字符串的长密码。

54.生成一个特定长度的字串。

操作符“X”是重复操作符。本行代码生成一个50个字符“a”组成的自串,并打印出来。 如果重复操作符用于列表上下文,他将生成由所给元素重复次数的一个列表(而不是标量)。

本行代码生成一个20次重复(1,2)的列表(看起来像(1,2,1,2,…))。

55.有一个字符串生成一个数组。

此处@months会保存包含来自于字符串中的月份名称的值。由于每一个月份名又空格隔开,split函数分割开他们并保存在@months数组中。于是$months[0]包含”Jan”, $months[1]包含”Feb”,…, $months[11]包含”Dec”。

另外一种方法是使用qw//操作符:

qw//操作符接收一个空格分割的字符,生成一个数组,每一个单词为数组中的一个元素。

56.由一个数组生成一个字符串。

@stuff = (“hello”, 0..9, “world”); $string = join ‘-‘, @stuff

此处,数组@stuff的所有值缩为一个字符串$string,之间用连字符分隔开。把一个数组转化为字符串使用join函数,join函数接收一个分隔符和一个列表,把列表中的所有元素连接为一个字符串,之间用指定分隔符隔开。

57.找出字串中字符的区位码

本行代码引入字符串“hello world”,利用split//,”hello world”把其分割为字符列表,接着用ord函数map每一个字符为8为区位码数字(比如ASCII或者 EBCDIC)。最后所有数字join连接在一起,用逗号隔开,并打印出来。 另一种实现同样功能的方法是使用unpack函数,指定C*作为unpack模板(C意思是无符号字符,*指所有字符):

58.转换ASCII码值列表为一个字串。

和上例我们看克unpack一个字串为值列表一样,我们也可以反过来他们pack回一个字串。 另一种方法,是利用chr函数,以码值为参数,返回相对应的字符:

和上面$55例相似,利用chr函数的map每一个@ascii的值为字符。

59.生成1到100所有奇数的数组。

本行代码生成从1到99的奇数组成的数组(1,3,5,7,9,…,99)。我们使用grep筛选列表1到100的各个元素,筛选代码用的是$_ % 2 ==。只有筛选代码评判为true的元素会返回。在本例中测试是否除2余数为1,如果是,这个数字为奇数,他会加到@odd数组中。 另外一种方法基于奇数具有低字节位为1的事实,并以此为测试:

表达式$_ & 1 分离出低字节位出来,并且grep筛选低字节位为1(奇数)。 关于字节见explanation of bit-hacks。

60.生成1到100所有偶数的数组

本行代码和上例基本上一样,除了grep test条件是偶数(能被2整除)。

61.计算字串的长度。

作为结束,length子程序返回字符串的长度。

62.计算数组元素个数

在标量上下文评估一个数组(或者哈希)的值会返回数组元素的数量。 另外一种计算方法是数组最后一个元素下表值加1:

此处,$#array返回数组@array的最后一个元素的下标值,由于下标由0开始所以最后一个元素的下标比数组个数小1,所以通过加1就可以获数组的元素个数。