Perl 语言学习笔记 (一)

来源:互联网 发布:软件系统故障处理要求 编辑:程序博客网 时间:2024/05/16 01:23
Perl是一种脚本语言。对于其详细的介绍,请自行查看维基百科http://zh.wikipedia.org/wiki/Perl或者百度百科http://baike.baidu.com/view/46614.htm?fr=aladdin。Perl语言的入门教材,推荐Randal L. Schwartz所著的 Learning Perl 一书。本书中文版的下载地址见http://pan.baidu.com/s/1qWnsWmK。我自己也是学习Perl的新手,因为处理一些Linux服务器的调度任务以及某些计算科学软件的源代码所以不得不去学习Perl。最近一段时间会陆续写一些学习Perl语言过程中的笔记,供同样在学习Perl语言的各位基友参考。
开始Perl语言的学习之前,你需要在计算机上安装Perl运行环境。对于使用Windows系统的计算机,可以安装ActivePerl或者Strawberry Perl等等现有的Perl运行环境;如果你的计算机是Linux或者UNIX或者Mac OS等等类UNIX操作系统,那么Perl往往是已经存在于系统中的组件,没必要再去安装(当然也可以自己去更新新版的Perl)。不过,个人感觉Perl语言主要还是面向Linux/UNIX系统的,Windows系统上没必要用Perl语言(因为Windows平台用PowerShell也可以做很多类似的事情)。所以,建议使用Linux系统开始Perl语言的学习——很简单,随便在虚拟机中安装一个ubuntu系统就可以。以下的笔记全部基于ubuntu 14.04 lts x64操作系统,Perl版本为5.18.2,不保证同样的代码适用于Windows平台。
建议:对于每一个Perl语言脚本,开头尽量都写成 
#! /usr/bin/perl
这一行指定了Perl的程序路径。如果你的Perl的可执行二进制文件不在/usr/bin这个路径下,那么只需要在这里写上你自己的Perl可执行文件的绝对路径即可。需要注意的是,绝对路径不要超过20个字符。所以,对于Perl可执行文件不在默认的/usr/bin路径下的情况,建议在shell中使用“ln -s”命令将在别处的Perl可执行文件链接到/usr/bin路径下。
如果要使用新版Perl的某些新功能,需要指定Perl的版本(譬如,5.10版本或者更新的版本),即再加一行 
use 5.010;
需要注意的是5.010表示v5.10版本的Perl,而5.100则表示v5.100版本的Perl(现在才到v5.20,估计这辈子不会有v5.100版了)。有了这行代码之后,该脚本只能在不低于指定版本的Perl上执行,比指定版本更旧的Perl则无法执行脚本。除了第一行的Perl路径声明以及以后代码中出现的花括号之外,每一行代码都以分号(英文标点)结尾。
Perl语言编程不需要什么特殊的代码编辑器,普通的文本编辑器就可以。对于Linux系统,直接在终端中使用vi或者vim就足够。需要注意的是完成的Perl脚本需要使用“chmod 777”这样的命令赋予可执行权限(所以属性不一定是777,不过777最简单省事。关于Linux系统的文件权限的详细解释,请查看之前的文章http://user.qzone.qq.com/476850491/blog/1398348056)。
好了,废话讲完,现在开始更新笔记。建议搭配 Learning Perl 这本书一起看。笔记中的引号的含义视该条笔记的语境而定,恕不再详细解释。
-------------------------------------------------------
Perl内部的数值全部按照双精度浮点数进行保存和运算,没有其他类型。
对于Perl,字符串就是一个整体,不按照单个字符进行组合。
Perl允许在整数直接量中插入下划线以便阅读,对程序没有影响。比如61234565432=61_234_565_432。
八进制直接量以0开头,十六进制直接量以0x开头,二进制直接量以0b开头。十六进制数的字母大小写不限。
可以用函数oct()或者hex()将对应进位制的直接量转变为十进制数字,其中oct()也可用于二进制直接量以及十六进制直接量的转换。oct()函数转换八进制数的时候,八进制数不以0开头;hex()函数转换十六进制数的时候,十六进制数也不以0x开头;oct()函数转换二进制数的时候,二进制数需要以b开头;oct()函数转换十六进制数,十六进制数必须以x开头。例如,oct(222)、hex(92)、oct(b10010010)、oct(x92)的结果均为十进制数字146。如果在oct()或者hex()函数中使用了开头的0,则会导致多次的转换,这是因为这些函数接受的参数都是以十进制的方式进行转换计算的。例如,八进制数377对应的十进制数为255,oct(377)的结果也为255,但是oct(0377)的结果则为173,原因是对于oct(0377)而言先将0377读取判断为八进制数,因为oct()函数接受的参数实际上是十进制数,所以转换为十进制数255,然后将255作为参数传递给函数oct(),oct()函数对255作为八进制数的转换就是173。另外一个例子可以验证刚才推测的“oct()函数接受的参数实际上是十进制”这一点,比如执行oct(0275)得到的结果是1,明显不对,这是因为Perl先读取0275,发现是八进制数,不符合oct()函数的参数要求,所以转换为十进制数189后将转换结果189传递给oct()函数作为参数,但是189是无法作为八进制数的(八进制数字的每一位只可能是0~7,不会大于7),所以转换会出错,得到荒谬的结果1。oct()与hex()函数的这种转换算法其实写的比较弱智,不过如果注意使用的话,转换速度也不错。
因为数值计算总是按照双精度浮点数来进行,所以10/3=3.3333...。另外,取模运算"%"总是先取整数再求余数,所以10.5%3.2和10%3的结果都是1。
乘幂操作符类似Fortran语言,即"**",所以2**3=8。
字符串长度没有限制,可以没有任何字符(即空字符串),也可以占满全部内存。字符串可以包含任何字符。需要注意的是,虽然支持但是Perl默认不会读取unicode字符,所以在使用unicode编码的时候,需要手动加上utf8编译指令"use utf8;"(推荐总是这样做)。
空字符NULL在Perl中没有特别的含义。Perl中的字符串不以NULL结束。
单引号内的字符串直接量(即'.....')中,除了单引号和反斜线字符之外,单引号内的字符都表示其本身(包括换行符,如果单引号内的字符串有多行的话)。只有在反斜线后面接续单引号或者另一个反斜线的时候,才表示转义。例如,'\'\\'一共有2个字符,即单引号后面接着反斜线;而'hello\n'一共有7个字符,除了hello这五个字母之外还有一个反斜线和n。
双引号内的字符串直接量(即".....")中,反斜线可以转义许多控制字符,或者用八进制或十六进制写法来表示任何字符。例如,"\n"表示输出一个换行符,"\t"表示输出一个制表符,"\x{2668}"则表示输出unicode中名为hot springs的字符。反斜线转义参看第35页表2-1。另外需要注意的是,双引号内的字符串可以实现变量内插,即将双引号内的变量名称替换成变量实际的值。
字符串可以用句号(必然是英文标点的句号)连接起来。比如如果代码是say "Hello,"." "."world!";那么执行后显示的是Hello, world!需要注意的是,连接运算必须显式使用连接操作符,不能像某些语言一样仅直接把字符串的两部分放在一起。
字符串重复操作符,即小写字母x。"5"x4就表示把字符串5重复4次,即结果是5555;"Perl"x(4+1)就表示把字符串Perl重复5次,结果是PerlPerlPerlPerlPerl。重复次数(即x操作符的右操作数)在执行操作前会先取整,即"5"x4.8的结果和"5"x4完全相同,因为4.8取整就是4。
数字与字符串之间的转换是自动进行的,这取决于操作符的要求。不需要担心字符串和数字之间的差异,只需要合理使用操作符,Perl会自动进行转换。
从字符串转换到数字的时候,如果以空格开头,则空格会被忽略(如果开头是很多个空格的话这些空格会被全部忽略,直到遇见第一个非空格字符为止),但是以非空格开头的话空格会被当做非数字字符处理;因为开头的空格无意义所以可以全部忽略,在已经忽略开头所有空格的基础上对字符串进行逐位的读取,非数字的字符及其之后的所有字符会被全部忽略。例如"12abcd 5"*"  3"的结果是36。这样的话,如果一个字符串以非数字字符开始(如果开头是空格则可以全部忽略,“非数字字符开始”指的是忽略掉开头空格之后的新的起始点),则这个字符串转换为数字的结果为0。例如,"   ab cd  123"转换为数字就是0。转换的时候只会按照十进制的方式进行处理,此时八进制、十六进制以及二进制的直接量都无法自动转换为十进制数字,只能作为字符本身的字面意思进行转换。所以,对于不同进位制的数字的转换,需要使用oct()函数或者hex()函数。
从数字转换为字符串就简单得多。比如代码"Z".5*"7"就相当于"Z"."35",结果是"Z35"。
使用use warnings;可以开启错误报告,或者在执行脚本时使用-w参数(perl -w, 或者在脚本第一行定义#! /usr/bin/perl-w)也可以实现这个效果。不同的是,warnings指令可以指定代码的作用范围,但是运行时的-w参数则是全局作用。
所谓标量变量,指的是单单存储一个值的变量。其名称以美元符号$开头,然后是变量的Perl标示符(由字母或者下划线开头)。标示符是区分大小写的。如果使用了utf8编译指令(use utf8;),那么也可以用其他非ASCII字符作为变量名。Perl通过变量名之前的美元符号来识别变量,所以不存在关键词冲突的问题。
双目赋值操作符与C语言类似,即$a+=1表示$a=$a+1,$a*=1表示$a=$a*1。甚至字符串的连接以及乘幂运算也可以使用这种简写方式,即$str.="a"表示$str=$str."a",以及$a**=3等价于$a=$a**3。
print作为“标准输出”,和C语言类似,除非特别指定,否则默认为屏幕输出。
字符串中的标量变量内插的方式可以在双引号内部(如"The answer is $answer"。另外注意,仅仅是双引号内部!单引号内部的字符会被按照本身来解释,即'$answer'就是字符串$answer,不是变量),也可以在双引号外部用连接符号连接起来(如"The answer is ".$answer)。如果一个字符串标量变量在被引用之前还未赋值或者赋值被清空,则其值为空。
事实上,输出字符串标量变量的内容的时候是不需要将其置于变量内插方式(也就是说不需要将其置于双引号内)的。
chr()函数可以取出对应代码点的unicode字符,效果上等于\x{}这种方式。另外,使用ord()函数(此函数接受的参数为一个unicode字符)可以获得作为参数的字符的代码点。
操作符的优先级以及结合性与C语言类似。比较操作符的写法略有不同,为<(对于字符串则为lt,下同)、<=(le)、==(eq)、>=(ge)、>(gt)、!=(ne)这几种。
if控制结构与C语言类似,即if(condition){...}else{...}这种结构。
Perl没有专用的boolean数据类型,判断条件为以0以及空字符串(即'')为假(需要注意的是,字符串'0'与数字0是同一个标量值,所以'0'也是假),其余数字以及字符串均为真。如果对象既不是数字也不是字符串,那么就先转换成数字或者字符串再进行判断。一言以蔽之,undef表示假,并且所有的引用都是真。
因为!可以颠倒真假值,所以连续用两次!会得到类似于boolean类型的结果,即返回1或者undef。不推荐使用这种方法,因为并没有规定返回值一定是1或者undef,虽然现阶段看起来是这样。
行输入操作符<STDIN>类似于一个标记,只需要将其放置在程序中希望返回标量值的位置上即可。执行脚本的时候,Perl会从标准输入读取一行文本(直到换行符为止)替换掉<STDIN>标记(替换时包括换行符)。chomp()函数可以去掉字符串变量末尾的换行符。即,使用chomp($input_text = <STDIN>)可以得到没有末尾换行符的输入文本。
while控制结构与C语言类似,即while(condition){...}这种形式。条件表达式在第一次执行循环之前就会被求值。
undef值当做数字使用,则是"0";当做字符串使用,则为空字符串""。但是undef本身并不是数值也不是字符串,而是另一种类型的标量值。与C/C++不同,undef值的存在不会对程序产生严重影响,Perl会自动根据情况将其作为数字0或者空字符串处理。另外,许多操作符在参数越界或者不合理时会返回undef。
defined()函数用来检查某个变量是否为undef类型。如果作为参数的变量是undef,则函数返回假,否则返回真。例如,对于<STDIN>,如果输入没有遇到换行符就被终止,则<STDIN>标记会返回undef。如果想要恢复一个变量至未使用过的初始状态,也可以对其赋值undef,例如$example = undef这样子。
--------------------------------------------------------------
第二章习题提示:
如果要实现显示a = 并且在这里进行输入的话,代码应该是 
print "a = ";
chomp($a = <STDIN>);
这样两行。因为print输出是推送到buffer的,所以下面这种代码是错误的: 
print "a = " . chomp($a = <STDIN>); 
0 0
原创粉丝点击