刚到公司第一个项目居然是做CGI 的开发,从来没有接触过,于是开始学习perl语言,网上搜了一个遍,文档不是很多,大部分都是一篇文章反复转载的,文章开头大部分都是说perl语言怎么简单,怎么灵活,稍微整理了一下开始看,按照经验,从-变量类型-数组-控制-循环-函数调用-内置函数。。一路开下来,两天下来觉得自己已经入门了,于是开始看原项目代码,结果90%的代码都看不懂,感觉很失败,perl语言真的太灵活了,在加上他们用了很多开发技巧,要掌握需要一定时间,幸好项目大部分都是对原系统的改造,希望能应付过关,下边是perl最基础部分的一些整理资料:
首先要知道,Perl是一种脚本语言。所谓的脚本,就是没有主函数,从最开始一行一行的按照顺序解释执行(老版Basic不也是如此吗)。因此,尽管把你的思路转化为流程用Perl表达出来吧。
其次,Perl的设计中参考了很多语言的长处,并避免了设计上的缺陷。因此Perl的很多语法你可能都会觉得似曾相识。我把Perl的语法总结了一下,和C语言做了一个简单的对比表格。表格左右两边的语句是C和Perl对应表达同一个功能各自的不同方式。如果读者有C语言的经验,相信看到这个对比可以很快的上手吧?
语法元素 |
C |
Perl |
Perl语法说明 |
注释 |
/* … */ |
# … |
只支持单行注释 |
变量 |
int a, b, c;
char c=’A’;
int x[10]; |
my ($a, $b, $c);
my $c='A';
my @x;
my %h; |
声明使用my标示
表示值的变量以$开头,表示数组的变量以@开头,表示哈希表的变量以%开头。
声明可以省略(不建议) |
字符串 |
char* h1=”hello\n”;
char* h2=”hello\\n”; |
$h1=”hello\n”;
$h2=’hello\n’; |
双引号解释内部的\n,而单引号则不解释 |
一维数组 |
int arr[10];
arr[0]=0;
for(i=0;i<10;i++)
arr[i]=i; |
my @arr;
$arr[0]=0;
@arr[3..5]=(3..5); |
数组声明以@标示
动态数组,不需要指定大小
数组下标从0开始
访问数组元素值的时候,要以$开头表示访问的是数值
[3..5]表示数组中下标为3到5之间的元素组成的数组
数组之间可以直接赋值 |
多维数组 |
int arr[10][10];
arr[0][1]=9; |
my @arr;
$arr[0][1]=9; |
Perl并不直接支持多维数组,而是以数组引用的方式间接支持。例如arr[0]的内容就是一个数组的引用地址。 |
指针 |
char c;
int* x=&c;
c='a';
printf(*x); |
my $c;
my $x=\$c;
$c='a';
print $x; |
\和C中的&类似,意思是取引用 |
|
void hello() {
printf(“Hello\n”);
}
void (*hi)()=hello;
(*p)(); |
sub hello{
print "Hello\n";
}
my $hi = *hello;
&$hi; |
&表示调用函数
*取函数的代码地址
不必用括号把参数括起来
调用时的括号也是可选的 |
条件语句 |
if (x>0) x=0;
x>0 ? x=0 : ; |
if ($x>0) { $x=0; }
$x=0 if $x>0;
$x=0 unless $x<=0;
$x>0 ? $x=0 : ; |
if 结构可以反转,意义不变,注意前句没有分号。
顾名思义, unless是“除非”的意思。这里的四个表达方式是等价的。注意第一种方式中,条件部分的圆括号和语句部分的花括号是不可省略的。 |
循环语句 |
略 |
foreach (@arry)
foreach my $key(@ary)
foreach $count (1..10) |
for/while的语法都和C类似。
foreach关键字也可以用for,意义不变。 |
函数 |
int max(int x, int y)
{
return x>y?x:y;
}
int n=max(1,2); |
sub max
{
my ($x, $y)=@_;
return $x>$y?$x:$y;
}
my $n=max(1,2) |
注意下划线”_”也是一个合法的变量名。而@_是Perl内置的一个数组,内容为函数的参数。
my ($x, $y) 表示声明了一个有两个元素的数组,并将两个元素映射到$x和$y上。
($x,$y)=@_;则表示两个数组之间的复制,@_中对应的元素的值就赋值给了$x和$y.这是一个简便的写法,也可以这样写
my $x=$_[0]; my $y=$_[1];
return是可选的,默认返回最后一个表达式的值 |
语法约束 |
1. 编译时打开编译器所有的警告选项
2. 使用lint工具 |
|
3. perl –w myprogram.pl 打开运行警告开关,如果运行时Perl检查到了可能的错误,会显示警告信息,否则它默认是什么也不提示继续执行。
4. #!/usr/bin/perl –w 在代码文件第一行中加入-w选项开关
5. use strict; 使用严格语法约束 |
运行 |
编译后直接执行 |
|
1. perl myprogram.pl 手工执行
2. #!/usr/bin/perl
Unix下在代码第一行加入,然后给文件加上可执行的属性 chmod +x myprogram.pl,之后就可以用./myprogram.pl命令来运行。
3. Windows下,安装ActivePerl的时候,已经将.pl后缀的文件和perl的解释程序关联起来了,因此直接双击文件图标就可以运行。 |
常见问题
1、程序的入口参数怎么取?
内置数组@ARGV包含了所有的运行参数。可以打印出来看看print @ARGV;
2、函数如何传参数、取参数?
每个函数内部都有一个内置的数组 @_ ,这个数组的元素就是函数的参数。例如传入的第一个参数就是$_[0],第二个是$_[1]。唔,如你所见,Perl的函数参数就是C中的动态参数。
3、默认变量是什么
这个可能会把你的头搞晕。有一个内置变量 $_ ,
4、显示消息、退出常见的简单写法
也可以在条件不满足的情况下使用
die ‘Configuration error’ unless($doc->getDocumentElement);
5、格式化输出
可以用简单的print语句进行一般的输出操作,如果需要复杂的格式化输出,可以使用printf语句……跟C的用法几乎是一样的。
printf("pi=%.6f", 355/113);
6、 =>是什么东西?
在使用Hash表的时候,可以经常看到=>这个符号。例如这样的一个定义:
my $account={
'Simon'=> 'simon@email.com',
'Jesse'=> 'jesse@email.com'
};
其实,=>符号跟逗号”,”是等价的。Perl里面的Hash表事实上是一个数组,只是把奇数位元素看做是Key(键),而把偶数位的元素看做是Value(值)。
7、关于引用的一点说明
Perl的引用类似C的指针,所谓的引用事实上就是地址。取一个变量的地址用反斜杠”\”操作符,例如 $p=\$x; 那么$p就是一个指向$x变量的指针。要引用指针的值,使用”$”操作符,例如 print $$p; 就是打印$x的值。
引用不单单可以引用变量,也可以引用数组、HASH表、函数,取函数的地址可以使用*操作符。
########################################
变量(1)--纯变量
Perl有三种变量:
一、纯变量
又称标量变量,是Perl处理的最简单的数据类型。标量可以是数字(如2,3或2.5e6)
,也可以是字符串(如“hello”和“网络教室”)。
Perl中的标量变量以美元符号$和一个字母开始,以后可以是字母、数字和下划线,
大小写有区别,而且所有字母、数字和下划线都有效。如:
$a和$A是不同的变量;
$this_is_a_long_variable_1和
$this_is_a_long_variable_2是不同的变量;
Perl中的变量可以通过操作符(如+或.等)来产生新的变量。你可以从文件和设备中
读取变量,也可以将其输出。
使用纯量变量时要在前面加上$符号, 注意:指定的纯变量是一个字符的话,就要加
上""双引号或单引号;如果是数值的话,就不用加上""这个符号。
标量数据又可以分为数字和字符串两种:
数字
可分为整型变量和浮点变量。
整型变量:(如2,-200,3568等)。Perl支持8进制和16进制变量,8进制以0开头(如025
5,表示8进制的255),16进制以0x或0X开头 (如-0x1a,代表负的1A)
实型变量:(如2.5,-6.3e5,-2.3-e6等)。
字符串
最短的字符串可以没字符,最长可以把你的内存填满,这与Perl的“无内置限制”
的原则一致。
字符串有两种格式:单引字符串和双引字符串。
单引字符串(single-quoted string): 就是用单引号括起来的一串字符。该单引字
符串不是字符串的一部分。引号中可以插入任何字符。只有两种情况例外,一种是中间
插入单引号,并在前面有一反斜杠;一种是字符串有两个连着的反斜杠。
双引字符串(double-quoted string): 就是用双引号括起来的一串字符,其作用类
似于C语言。
双引字符串中反斜杠转义表
结构含义
\n 换行
\r 回车
\t 水平置表符
\f 换页符
\b 退格
\v 垂直置表符
\a 响铃
\e Esc
\007 任一八进制ASCII值(这里007表示bell)
\x7f 任一十六进制ASCII值
\cC 任一“控制”字符
\\ 反斜杠
\" 双引号
\l 下一字母小写
\L 以后所有字母小写直到\E
\u 下一字母大写
\U 以后所有字母大写直到\E
\E 结束\L和\U
标量变量的运算符
1、赋值运算符
如:$a=23; #将23赋值给$a
$b=$a=23; #将23赋值给$a和$b
$b=3+($a=2); #将2赋值给$a,再加3将值赋给$b,即$b为5
2、二元赋值运算符
如:$a=+3; #等同于$a=$a+3
这与C语言中基本相同。
3、自增自减运算符
如:$a++; #等同于$a=$a+1
这与C语言中基本相同。
4、chop()运算符
如:$a="hello";
chop($a); #此时$a的值为"hell"。
这对于从屏幕获取文本后去除换行符很有用。
如:$a=; #获取文本
chop($a); #去除最后的换行符。
这两行可合并为:
chop($a=);
5、字符串的标量插入值
如:$a="zmd";
$b="hello! $a";
$b的值为"hello! zmd"。
综合示例
$url1='hello'; #将hello这串字符赋给$url1变量;
$url2='don\'t'; #将don't这串字符赋给$url2变量;
$url3='hello\n'; #将hello\n这串字符赋给$url3变量;注意\n不被当作换行符而是\和n
两个字符;
$url1=" #将这串字符赋给$url1变量
$url2="/cgi-bin/"; #将/cgi-bin/这个字符赋给$url2变量;
$url3=$url1.$url2; #将两个变量的字符串连起,
$url3="
$int=5; #将10赋给$int变量;
$int=5+6; #$int=11;
$int=5*6; #$int=30;
$int=5;$int++; #$int=6;
$int=5;$int+=8; #$int=13;
$a="\Uzmd";$b="\u\LZHENG";$c="$a $b" #$a="ZMD"; $b="Zheng";
$c="ZMD Zheng"
Perl变量(2)--数组
<../../../../images/line1.gif>
二、数组
数组是标量数据的有序列表。
数组可以含任意多个元素。最小的数组可以不含元素,而最大的数组可以占满全部
可用内存。
数组实量(array literal)是位于括号内用逗号分开的一系列值。如:
(1,2,3,4,5)#具有1,2,3,4,5五个数值的数组
("zmd",1974,173.5)#具有"zmd",1974,173.5三个数值的数组
()#空数组
($a,5)#两个数值:$a的值和5
($a+$b,6)#两个数值
数组变量具有单独的数组值,要以@打头而不是$。如:
@zmd
注意@zmd与$zmd没任何联系。Perl为对象的不同类型保留独立的命名空间。
数组的赋值和标量赋值一样,也用等号表示。Perl根据赋值对象是标量还是数组变量来
确定赋值操作是标量赋值还是数组赋值。
若数组实量中只含有变量引用(不是表达式),则此数组实量也可作为变量使用。它可以
用在赋值运算符的左边。例如:
($a,$b,$c)=(1,2,3) #将1赋给$a,2赋给$2,3赋给$3
如果把数值变量赋给标量变量,则赋给标量变量的就是数组长度,如:
@zmd=(1,2,3) # 将(1,2,3)赋给@zmd
$a=@zmd # $a为3,即@zmd的数组个数
数组元素的访问和C语言中类似,下标是按顺序整数排列的,编号从0开始。
($a,$b,$c)=(1,2,3) #将1赋给$a,2赋给$2,3赋给$3
如果把数值变量赋给标量变量,则赋给标量变量的就是数组长度,如:
@zmd=(1,2,3) # 将(1,2,3)赋给@zmd
$a=@zmd # $a为3,即@zmd的数组个数
综合举例
@user1=("zmd","cxm"); #将zmd和cxm两个字符串赋给@user1
@user2=@user1; #这时@user2=@user1=("zmd","cxm")
@user3=("zk",@user1); #这时@user3=("zk","zmd","cxm")
($one,@user4)=@user3; #这时$one="zk"
@user1=(); #把@user1清空
@int1=(1,2,3,4,5); $x=@int1; #将数组@int1的个数赋给$x纯变量,$x=5
$x=$#int1; #$#这个变量返回数组最后个数的值(index)$x=4
($x)=@int1; #$x等于数组的第一个个数值$x=1
$b=$int1[0]; #$b等于数组的第一个元素值$b=1
$c=@int1[0]; #$c同上$c=1,因些呼叫数组中值有两种方法
$int1[0]=3; #将3这个数值赋给数组@int的第一个元素@int1=(3,2,3,4,5)
$int1[0,1]=[7,8]; #将7赋给数组的第一个元素将8赋给数组第二个元素@int1=(7,8,3,4 ,5)
@int1[0,1]=@int1[1,0]; #将数组前两个元素交换@int1(8,7,3,4,5)
($int1[0],$int1[1])=($int1[1],$int1[0]); #同上@int1=(8,7,3,4,5)
@int2=@int1[0,1]; #int2=(8,7)
$int1[5]=6; #将6赋给数组中第六个元素@int1=(1,2,3,4,5,6)
Perl变量(3)--关联数组
三、关联数组
关联数组和前面说的数组类似,它包含标量数据,可用索引值来单独选择这些数据
,和数组不同的是,关联数组的索引值不是非负的整数而是任意的标量。这些标量称为
Keys,可以在以后用于检索数组中的数值。
关联数组的元素没有特定的顺序,你可以把它们想象为一组卡片。每张卡片上半部
分是索引而下半部分是数值。
关联数组是Perl语言中特有的,关联数组是一个功能强大的数组。使用关联数组时
要在前面加上%号,关联数组的格式如:
%ARRAY=(key1,value1,key2,value2,key3,value3);
每一个key都有一个相对应的值(value)。
和数组类似,$zmd,@zmd,%zmd之间没有任何联系。Perl为对象的不同类型保留独立
的命名空间。
下面介绍关联数组的操作:
在关联数组中增加、更改一对数据:ARRAY={key}=value; 在关联数组ARRAY中加上
一对key-value,要在关联数组名称前加上$号,而且key的名称要在{}符号之间,最后再
指定key所对应的value值。如果在这个关联数组中已经有这个key了.就会更改这个key所
对应的value。keys(%array)操作符可生成由关联数组%array中的所有当前关键字组成的
列表。即返回奇数个元素(第1,3,5,7...个)的列表。
values(%array)操作符返回由关联数组%array中所有当前值组成的列表,即返回偶数个
列表。
echo(%array)操作符返回由一个关键字和一个值对构成的两个元素的表。对同一数组再
操作时返回下一对值直至结束。若没有更多的对时,echo()返回空表。 (这在打印全部
列表中很有用)
删除一对在关联数组中的数据:delete $ARRAY{key};delete 是 Perl 所提供的函数,
作用是删除关联数组中的一个key以及这个 key 所对应的 value。使用方法是 在
delete 函数之后,指定关联数组中要删除的key名称。
关联数组的综合举例:
%fred=(one,"zmd",two,"cxm"); $a=$fred{one}; #$a等于"zmd"
$b=$fred{two}; #$b等于"cxm"
$fred{two}="yes"; #%fred=(one,"zmd",two,"yes")
@ list =keys(%fred); #@list=(one,two)
@user=values(%fred); #@user=("zmd","cxm")
($number,$name)=echo(%fred); #此时$number的值为one,$name的值为"zmd",再执行一次$number为值为two,$name的值为"cxm")
@a=%fred; #将关联数组fred指定给数组a,这时@a=(one,"zmd",two,"cxm")
%b=@a; #将数组a指定给关联数组b,这时%b=(one,"zmd",two,"cxm")
delete $fred{one}; #将关联数组中key值为one的一对key-value删除,这时%fred=(two
,"cxm")
%name=(); #把%name关联数组置空
Perl的运算符号字符
符号范例说明
= $x = $y; 将$x的值指派给$y
+= $x += $y; $x=$x+$y; 将$x加$y之后再指派给$x
-= $x -= $y; $x=$x-$y; 将$x减$y之后再指派给$x
*= $x *= $y; $x=$x*$y; 将$x乘$y之后再指派给$x
/= $x /= $y; $x=$x/$y; 求出$x除以$y之后的商数,再指派给$x
**= $x **= $y; $x=$x**$y; 将$x乘上$y次方之后再指派给$x
%= $x %= $y; $x=$x%$y; 求出$x除以$y的余数以后,再指派给$x
.= $str1 .= $str2; $str1=$str1.$str2; 将$str1这个字符串再加上$str2这个字符串
之后,再指派给$str1这个字符串
x= $str x= $y; $str=$strx$y; 重复$str字符串$y次,并反结果指派给str这个字符串
算术(Arithmetic)运算符
符号范例说明
+ $z = $x+$y
将$x和$y相加之后,再将结果指派给$z
- $z = $x-$y 将$x减掉$y之后,再将结果指派给$z
* $z = $x*$y 将$x和$y相乘之后,再将结果指派给$z
/ $z = $x/$y 将$x除以$y之后,再将商数指派给$z
% $z = $x%$y 将$x除以$y之后,再将余数指派给$z
** $z = $x**$y 将$x乘以$y之后,再将结果指派给$z
++ $x++;
++$x; 如同$x=$x++1;将$x加一以后再将结果指派给$x
-- $x--;
--$x;
如同$x=$x-1;将$x减一以后再将结果指派给$x
. $z = $x.$y 将$x字符串和$y字符串连接之后,再将结果指派给$z
数值(Numeric Values)关系运算符
符号 范例 说明
> $x > $y 如果$x大于$y,返回1的值,否则返回0
>= $x >= $y 如果$x大于等于$y,返回1的值,否则返回0
< $x < $y 如果$x小于$y,返回1的值,否则返回0
<= $x <= $y 如果$x小于等于$y,返回1的值,否则返回0
== $x == $y 如果$x等于$y,返回1的值,否则返回0
!= $x != $y 如果$x不等于$y,返回1的值,否则返回0
<=> $x <=> $y 如果$x大于$y,返回1的值,如果$x等于$y,否则返回0;&127;如果 $x小
于$y,则返回-1的值
字符串(String Values)关系运算符
符号 范例 说明
gt $str1 gt $str2 如果$str1大于$str2,返回1的值,否则返回0
ge $str1 ge $str2 如果$str1大于等于$str2,返回1的值,否则返回0
lt $str1 lt $str2 如果$str1小于$str2,返回1的值,否则返回0
le $str1 le $str2 如果$str1小于等于$str2,返回1的值,否则返回0
eq $str1 ep $str2 如果$str1等于$str2,返回1的值,否则返回0
ne $str1 ne $str2 如果$str1不等于$str2,返回1的值,否则返回0
cmp $str1 cmp $str2 如果$str1大于$str2,返回1的值,如果$str1等于$str2,返回0,如
果$str1小于$str2,则返回-1的值
逻辑(Logical)运算
1 $x&&$y(And)
$x $y 结果
真(True) 真(True) 真(True)
真(True) 假(False) 真(True)
假(False) 真(True) 假(False)
假(False) 假(False) 假(False)
2 $x||$y(Or)
$x $y 结果
真(True) 真(True) 真(True)
真(True) 假(False) 真(True)
假(False) 真(True) 真(True)
假(False) 假(False) 假(False)
3 $x(Not)
$x 结果
真(True) 假(False)假(False) 真(True)
其它常用的运算符
指令:..区块运算符(Range Operator)
说明:这个运算符是Perl语言中特有的运算符,是一个很实用的运算符.
范例:
@digits=(1..9); #此时@digits=(1,2,3,4,5,6,7,8,9);
@digits=('01'..'05'); #此时@digits=(01,02,03,04,05);
@char=('A'..'E'); #此时@char('A','B','C','D','E',);
@total=(1..3,'A'..'B'); #此时@total=(1,2,3'A','B');
指令: 判别运算式?运算1:运算式2 条件运算符(Conditional Operator)
说明: 这个语法的意义和C语言一样,如果判别运算式的值是真(True)的话,则做运算
,1的运算,如果判别运算式是假(False)的话,则做运算式2的运算.
范例:
$price=($age>60)? 100:200;
如果$age大于60的话,则$price等于100,否则$price等于200.
常用的文件数据(File test)运算符
范例 说明
-r $file 如果$file是可读取的话,返回1的值
-w $file 如果$file是可写入的话,返回1的值
-x $file 如果$file是可执行的话,返回1的值
-e $file 如果$file存在的话,返回1的值
-o $file 如果$file是被执行才所拥有的话,返回1的值
-s $file 返回$file的文件大小(bytes)
-f $file 如果$file是正常文件的话,返回1的值
-T $file 如果$file是文本文件的话,返回1的值
-B $file 如果$file是Binary文件的话,返回1的值
-M $file 返回$file文件最后一次更改时间到现在的日期数