Files
devops/perl/perlonelinecn-master/04字符和数组生成.md
2025-09-17 16:08:16 +08:00

146 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 字符和数组生成
## 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次重复12的列表看起来像1212,…))。
## 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的奇数组成的数组13579,…,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就可以获数组的元素个数。