# 文本转化和替换 ## 63.ROT13化字串 'y/A-Za-z/N-ZA-Mn-za-m/' 本行代码使用y操作符(或者页脚tr操作符)做ROT13转化。y和tr操作做会对搜索列表的字符以替换列表对应位置的字符逐字替换。 本行代码A-Aa-z生成如下的字符列表: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz 而N-ZA-Mn-za-m 生成的列表为: NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm 如果你观察的比较仔细的话,就可以看出来第二行列表实际上和第一个列表偏移了13个字符。于是用y操作符把第一个列表所有字符用第二列表替换,你正好就执行了ROT13操作。 如果你要对整个文件做ROT13: perl -lpe 'y/A-Za-z/N-ZA-Mn-za-m/' file -p参数会把文件的每行都放到$_变量中,y做ROT13操作,在用-p输出$_out.-l参数附加一个换行符。 注意:ROT13两次会得到同样的字符。例如,ROT14(ROT13(string))==string。 ## 64.Base64加密 perl -MMIME::Base64 -e 'print encode_base64("string")' 本行代码使用MIME::Base64模块(Perl核心自带,无需额外安装)。这个模块的encode_base64函数接受字串为参数,对其做Base64加密。 如果对整个文件做加密,使用下面代码: perl -MMIME::Base64 -0777 -ne 'print encode_base64($_)' file 此处-0777参数和-n用在一起导致Perl加载整个文件到$_变量。接着对其中base64加密,就像上面的字串的例子一样的。 如果我们不加载整个文件,而是通过逐行加密的话结果会混乱。 ## 65.base64解码 perl -MMIME::Base64 -le 'print decode_base64("base64string")' MIME::Base64模块也有解码函数decode_base64.decode_base64函数接收base64加密的字串,对其进行解码。 对这个文件解码也可以很简单: perl -MMIME::Base64 -ne 'print decode_base64($_)' file 此处不需要加载整个文件到$_,因为base64加密的文件每一行都恰好为76个字符,很好解码。 ## 66.对字串URL转码 perl -MURI::Escape -le 'print uri_escape($string)' 你需要安装另外URI::Escape模块,这个模块输出两个函数uri_escape 和uri_unescape,第一做url转码,另一个做URL解码。 ## 67.对字串URL解码 perl -MURI::Escape -le 'print uri_unescape($string)' 本行代码使用uri_unescape函数做URL解码。 ## 68.对字串做HTML转码 perl -MHTML::Entities -le 'print encode_entities($string)' 本行代码使用HTML::Entities 模块的encode_entities函数。这个函数用来转码HTML实体。例如,把 < 和 >转化为<和> ## 69.对字串做HTML解码 perl -MHTML::Entities -le 'print decode_entities($string)' 本行代码使用HTML::Entities 模块的deencode_entities函数。 ## 70.所有文本大写 perl -nle 'print uc' 本行代码使用uc函数,它默认对$_变量进行操作,并且返回其大写形式。 另外一种方法是用-p命令行选项使其自动打印$_变量并且对其就地处理: perl -ple '$_=uc' 也可通过使用\U转义序列的方法达到同样的功能: perl -nle 'print "\U$_"' 这会让其后所有的字符(或者直到出现\E为止)都大写。 ## 71.所有文本小写 perl -nle 'print lc' 本行代码和前一例完全相似,不过此处使用的lc函数爸$_的内容转化为小写。 或者,使用转义序列\L做字符改写: perl -nle 'print "\L$_"' 此处\L会让其后所有的字符(或者直到出现\E为止)都小写。 ## 72.对每行的首字母大写 perl -nle 'print ucfirst lc' 本行代码使用lc函数使输入的转化为小写,并利用ucfirst函数似的第一个字字符大写。 也能用转义码文本转换的方法实现同样的功能: perl -nle 'print "\u\L$_"' 第一个\L使整行都小写,\u使得第一个字符大写。 ## 73.大小写转化 perl -ple 'y/A-Za-z/a-zA-Z/' 本行代码把大写字母A-Z转化为小写a-z,而把小写字母大写,从而实现了大小写转化。 ## 74.每行进行驼峰大小写转化 perl -ple 's/(\w+)/\u$1/g' 这是一个差劲的驼峰表示法行代码。它会把每个单词的首字母都大写。对诸如“fried’s car”会转化有误,会把它转化为“ Friend'S Car”。 一个改进是: s/(?)) { if ($line =~ /baz/) { $line =~ s/foo/bar/ } } 他先检查每行是否匹配“baz”,如果匹配,则替换行中foo为bar。 ## 82.逆序输出段落 perl -00 -e 'print reverse <>' file 本行代码使用了-00参数,这在例7讨论过,用来开启大段落模式,意味着Perl将通过段落的方式读取文本,而不是默认的按行的方式。接着使用<>操作符使得Perl用指定的文件或者标准输入获得输入。本处我们指定file作为参数,所以Perl读取file的文本段落(由于-00)。当Perl读完文件,它将所有段落作为一个列表返回,并且调用reverse函数颠倒段列表的顺序。最后打印出反序的段落列表。 ## 83.逆序输出所有行 perl -lne 'print scalar reverse $_' 本行代码在标量上下文下reverse操作。在上一例中,对整个列表在在列表上下文中执行reverse,结果是对列表元素顺序进行反序。对标量变量,比如包含整行的$_你要实现同样的功能必须在标量上下文进行reverse操作。否则,它执行的将会对一个元素的列表rreverse,得到结果还会是他自己!作为操作后,打印出反序的行。你可以去掉代码中$_,执行结果一样的。因为reverse默认的变量就是$_。换句话说,行代码可以写为: perl -lne 'print scalar reverse' 或者你可以用-p替换-n,修改$_变量,使其值为倒序: perl -lpe '$_ = reverse $_' 也可以简写为: perl -lpe '$_ = reverse' 要说明的是在Perl的操作符如果没有指定参数的话,大多数情况下默认都是对$_操作。 ## 84.以逆序方式打印列 perl -alne 'print "@{[reverse @F]}"' 本行代码对文件中的列逆序转化。-a命令行参数用空格为分隔符切割每一行为列并存在@F数组中。接着对其逆序并且打印。 本行代码在以有过类似的例子,@{[...]}结果,为了解释其作用,我们假设在其中插入了双引号,给予下面的输入文件: one two three four five six seven eight 其输出为: four three two one eight seven six five 如果输入的行的各列直接不是空格而是其他的分隔符,则我们必须用-F命令行设置为特殊的字符,如果给输入文件为: one:two:three:four five:six:seven:eight 这我们增加-F:参数,给行代码: perl -F: -alne 'print "@{[reverse @F]}"' 它的输出为: four three two one eight seven six five 注意到,在输出的时候没有带:字符,为了使其带上,我们需要对本行修改,设置$”变量为“:”,如下: perl -F: -alne '$" = ":"; print "@{[reverse @F]}"' 他会输出我们所期望的结果: four:three:two:one eight:seven:six:five 变量$”用于改变在双引号环境下对数组进行变量内插打印时元素间默认的分割字符(空格)。