一、简单变量
===========
1. 整型
$x = 123456;
PERL中将整型数据存放在浮点寄存器中,实际上整型变量在PERL中是当作浮点数来看但,只不过是一种浮点数据的特列。
8进制数据以0打头
$var1 = 047(十进制39)
16进制数据以0x打头
$var2 = 0x1f(十进制31)
2. 浮点型
浮点寄存器通常是不能精确的存储浮点数,会产生误差。使用浮点数时需要注意指数范围通常是-309到+308。
e.g.
11.4, -0.3, .3, 3., 64.1e+02, 5.4e04
$value = 9.01e+21 + 0.01 - 9.01e+21; (value为0)
$value = 9.01e+21 - 9.01e+21 + 0.01; (value为0.01)
3. 字符串
PELR中字符串的结尾没有C语言中的'/0',需要注意。
PERL中的字符串支持单引号和双引号两种操作,但是有不同:
双引号的字符串支持简单的变量替换:
$number = 11;
$text = "This text contains the number $number.";
同时双引号字符串支持转义字符:
/a Bell
/b Backspace
/cn The CTRL + n character
/e Escape
/E End the effect of /L, /U or /Q
/f Form feed
/l Forces the next letter into lowercase
/L All following letters are lowercase
/n Newline
/r Carriage return
/Q Do not look for specifial pattern characters
/t Tab
/u Force next letter into uppercase
/U All following letters are uppercase
/v Vertical tab
若要在字符串包含双引号或者反斜线,则需要在之前加入一个反斜线作为转义:
$res = "A quote /" and A backslash //";
单引号与双引号有2个区别:1.没有变量替换功能, 2.反斜线不支持转义字符
在PERL中所有的变量缺省都为undef
二、操作符
=====
1. 算术操作符
a)乘幂的基数不能为负:(-5)**2
b)乘幂结果不能超出计算机表示范围:10**99999
c)取余操作数如果不是整数,则四舍五入成整数后运算,运算符右边不能为0
d)单目负可用于变量:-$y(等效$y*-1)
2.整数比较操作符
< 小于
> 大于
== 等于
<= 小于等于
>= 大于等于
!= 不等于
<=> 比较,返回1,0或-1(0两值相等,1第一个值大,-1第二个值大)
e.g.
$value1 = 20;
$value2 = 30;
print $value1 <=> $value2;
结果为-1
3.字符串比较操作符
lt 小于
gt 大于
eq 等于
le 小于等于
ge 大于等于
ne 不等于
cmp 比较,返回1, 0或-1
4. 逻辑操作符
||(or) 逻辑或
&&(and) 逻辑与
!(not) 逻辑非
xor 逻辑异或
5. 位操作符
& 位与
| 位或
~ 位非
^ 位异或
<< 左移位
>> 右移位
PS:若$用于负整数,则PERL会将其转化成无符号数
6. 赋值操作符
=
+=
-=
*=
/=
%=
**=
&=
|=
^=
7. 自增,自减
8. 字符串联结和重复操作符
联结: .(.=)
重复: x
e.g.
$newstring = "potato" . "head";(等于"potatohead")
$newstring = "t" x 5(等于"ttttt")
9.逗号操作符
逗号前的表达式先会被计算
$var1 +=1, $var2 = $var1;
等于:
$var1 += 1;
$var2 = $var1;
$var = 26;
$result = (++$var, $var + 5);(result为32)
10.条件操作符
$result = $var == 0 ? 14 : 7
11. 操作符优先序列
二、列表和数组变量
================
1. 列表
列表是包含在括号里的一序列值,可以是任何数值,也可以为空。
e.g.
(1, 4.3, "Hello", 55)
()空列表
PS:含有一个数值的列表((4.3))和该数值本身(4.3)是不同的,但是可以转化
(17, $var, "a string")
(17, 256 << 2)
2. 数组(@)
列表存储在数组变量中,与简单变量不同,数组变量以"@"打头
@array = (1, 2, 3);
数组变量创建时初始化值为空列表(),而且由于PERL用@和$来区分数组变量和简单变量,因此可以使用同一个名字表示数组变量和简单变量。
e.g.
$var = 1;
@var = (11, 23, $var);
数组存储
对于数组中的值可以通过下标访问,第一个元素下标为0。若试图访问不在的数组元素时,结果为NULL,但如果给超出数组大小的元素赋值,则数组会自动增长,其中增长的元素填充NULL值。
e.g.
@array = (1, 2, 4, 5);
$scalar = $array[0];
$array[3] = 4; #array is (1, 2, 4, 4)
$scalar = $array[4]; # $scalar is null
$array[6] = 17; # @array is (1, 2, 4, 4, "", "", 17)
数组拷贝
@result = @original
用数组给列表赋值
@list1 = (2, 4, 5);
@list2 = (1, @list1, 65);
对简单变量赋值
@array = (2, 3, 4);
($var1, $var2, $var3) = @array;
字符串中的方括号和变量替换
"$var[0]" 数组中的第1个元素值
"$var/[0]" 等于"$var"."[0]"
"${var}[0]" 等于"$var"."[0]"
"$/{var}" 等于${var}
列表范围
(1..10) = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
(3..3) = (3)
(2.1..5.3) = (2.1, 3.1, 4.1, 5.1)
(4.5..1.6) = ()
("aaa".."aad") = ("aaa", "aab", "aac", "aad")
($var1..$var2+4)
数组输出
print ("@array/n")
数组长度
若数组变量出现在预期简单变量出现的地方,则PERL解析为其长度
@array = (1, 2, 4)
$scalar = @array; # $scalar = 3
($scalar) = @array; # $scalar = 1
上面的表达式,实际上把$scalar看成是一个获取列表元素的表达式了,因此实际上获取的是列表array的第一个元素的值.
e.g.以数组长度遍历列表
$count = 1;
while ($count <= @array) {
print ("Element $count: @array[$count - 1]/n");
$count++;
}
子数组
@array = (1, 2, 3, 4, 5);
@subarray = @array[0, 1]; # @subarray=(1, 2)
@subarray2 = @array[1..3]; # @subarray=(2, 3, 4)
@array[0,1] = ("string", 24) #@array = ("string", 24, 3, 4, 5)
@array[1,2] = @array[2,1] 用子数组形式交换两个元素
数组相关函数
sort - 按字符顺序排序
@array = ("this", "is", "a", "test");
@array2 = sort(@array); # @array2=("a", "is", "test", "this")
reverse - 反转数组
@array2 = reverse(@array);
chop - 数组去尾
去掉STDIN输入字符串时最后一个字符-换行符,若用到数组上,则对数组的每一个元素都进行去尾处理。
@list = ("rabbit", "12345", "quartz");
chop (@list); # @list = ("rabbi", "1234", "quart")
join/split - 连接/拆分
join的第一个参数是连接所用的分割符,其余为待连接的字符数组
$string = join(" ", "this", "is", "a", "string"); # "this is a string"
$string = "words::and::clons"
@array = split(/::/, $string); # @array=("words", "and", "colons");
三、文件读写
===========
1. 打开、关闭文件
open (filevar, filename)
filevar: 文件句柄
filename: 文件名
PERL中有三种访问模式:读、写、添加。写模式会将原有数据覆盖,而添加模式,是在文件末尾加入新内容。但是不能对文件进行读写/添加操作
open(MYFILE, "myfile") 读
open(MYFILE, ">myfile") 写
open(MYFILE, ">>myfile") 添加
文件打开处理:
if (open(MYFILE, "myfile)) {
# here's what to do if the file opened succesfully
}
unless(open(MYFILE, "myfile")) {
die ("Can not open input file!/n");
}
open(MYFILE, "myfile") || die ("Could not open file.");
使用完毕后需要用close(MYFILE)关闭文件
读文件操作
$line = <MYFILE> 从文件中读取一行数据到变量$line中,并且把文件指针向后移动一行。对于<STDIN>不需要打开文件,即可操作
@array = <MYFILE> 把文件全部内容读入数组@array,文件每一行(包含回车)为@array的一个元素。
写文件
open(OUTFILE, ">outfile")
print OUTFILE ("Here is an output line./n")
PS: STDOUT, STDERR为标准输出和标准错误文件,通常为终端,因此不需要打开文件
处理文件状态
-op expr
e.g.
if (-e "path/file1") {
print STDERR ("File exists./n");
}
-b 是否为块设备
-c 是否为字符设备
-d 是否为目录
-e 是否存在
-f 是否为普通文件
-g 是否设置了setgid位
-k 是否设置了sticky位
-l 是否为符号连接
-o 是否拥有该文件
-p 是否为管道
-r 是否可读
-s 是否非空
-u 是否设置了setuid位
-t 是否表示终端
-w 是否可写
-x 是否可执行
-z 是否为空文件
-A 距上次访问多长时间
-B 是否为二进制文件
-C 距上次访问文件的inode多长时间
-M 距上次修改多长时间
-O 是否只有真正用户所有
-R 是否只有真正用户可读
-S 是否为SOCKET
-T 是否为文本文件
-W 是否只有真正用户可写
-X 是否只有真正用户可访问
命令行参数
@ARGV是PERL中的命令行参数数组,但是@ARGV[0]并不是代表文件名,而是第一个参数。
$var = $ARGV[0]; #第一个参数
$number = @ARGV; #参数个数
PERL中<>操作符,实际上是对数组@ARGV的隐含引用:
1. 当PERL解析器第一次看到<>时,打开以$ARGV[0]为文件名的文件
2. 执行动作shift(@ARGV); 把数组@ARGV的元素向前移动一个,其元素量减少1
3. <>操作符读取在第一步打开的文件中的所有行
4. 读完后,解析器回到第一步重复
e.g.
@ARGV = ("myfile1", "myfile2"); #实际上是由命令行参数赋值
while ($line = <>) {
print ($line);
}
把文件myfile1和myfile2的内容打出来。
打开管道
open (MESSAGE, "| cat > hello")
等价于
open (MYPIPE, ">hello")
四、模式匹配
===========
五、控制结构
===========
1)条件判断
if (<expression>) {
<statement_block_1>
} elseif (<expression>) {
<statement_block)2>
}
...
else {
<statement_block_n>
}
2)循环
a)while循环
while (<expression>) {
<statement_block>
}
b)until循环
until(<expression>) {
<statement_block>
}
c)for循环
for ($count = 1; $count <= 5; $count++) {
# statements inside the loop go here
}
d)foreach循环
foreach localvar (listexpr) {
statement_block;
}
e.g.
foreach $word (@words) {
if ($word eq "the") {
print ("found the word 'the'/n");
}
}
e)do循环
do {
statement_block
} while/until(condexpr)
f) 循环控制
退出循环last(C的break)
执行下一个循环next(C的continue)
redo重复此次循环,循环变量不变,但是redo在do循环中不起作用。
g)goto
goto label;
3)单行条件语句
statement keyword condexpr
其中keyword:if, unless, while, until
e.g.
pirnt ("This is zero./n") if ($var = 0);
print ("This is zero./n") unless ($var != 0);
PS:虽然条件判断在后面,但是是先行执行。
六、子程序
=========
1. 定义
sub subroutine{
statements;
}
2. 调用(&)
&subname;
...
sub subname {
...
}
3. 先定义后使用可以省略&符号
sub subname {
...
}
subname;
4. 向前引用,现定义字程序名,后定义子程序体
sub subname;
...
subname;
...
sub subname {
...
}
5. 用do调用
do my_sub(1, 2, 3);#等价&my_sub(1, 2, 3);
6. 返回值
缺省情况,子程序最后一个语句作为返回值
7. 局部变量
my 定义的变量只在该子程序中存在
local定义的变量不存在于主程序中,但是存在在该子程序和该自春光许调用的子程序中
e.g.
my ($scalar) = 43;
local(@array) = (1,2,3);
8. 参数传递
&sub1($number1, &number2, &number3);
...
sub sub1{
my($number1, $number2, $number3) = @_;
...
}
9. 传送数组
&addlist (&mylist);
&addlist ("14", "6", "11");
sub addlist {
my (@list) = @_;
...
}
当参数为数组的时候,子程序只能将其赋给一个数组变量
10. 别名传递数组参数(引用传递)
@myarray = (1, 2, 4, 5);
&my_sub(*myarray);
sub my_sub {
my (*subarray) = @_;
}
在定义数组别名后,如果有相同的简单变量,则对该简单变量的操作同样会影响到别名数组。
11. 预定义子程序
PERL5中预定义了三个子程序:
BEGIN子程序在程序启动时候调用
END子程序在程序结束时被调用
AUTOLOAD在找不到某个子程序时被调用
e.g.
BEGIN {
print ("Hi! welcome./n");
}
AUTOLOAD {
print ("HHH/n");
}
若预定义子程序定义了多个,BEGIN按顺序执行,END按逆序执行。
七、关联数组
八、格式化输出
九、文件系统
十、引用(指针)
=============
PERL5中有两种类型的引用类型:硬引用和符号引用。符号引用包含变量的名字,它对于运行时创建变量名,并定位很有用处。基本上,符号引用就像文件名或UNIX系统中的软连接。而硬引用则像文件系统中的硬连接。
硬引用跟踪引用计数器,当其数为0时,PERL自动将被引用的数据释放,如果该数据是对象,则析构释放到内存池中。对于非简单变量的引用必须显示的解除引用,并且告诉其应当如何做。
1)使用引用
任何简单变量均可保存硬引用,因为数组和哈西表含有多个简单变量,所以可以建立多种组合而成的复杂的数据结构,如数组的数组,哈西表的数组。
取地址:
如果$pointer的值为一个数组的指针,则@$pointer可以访问数组中的元素,表示取出$pointer中的地址值当作数组使用。类似%$pointer表示指向哈西表中的第一个元素的引用。
创建使用引用
反斜线(/)与C语言中传递地址操作符类似(&),PERL中用'/'符号创建一个新的引用:
$variavle = 22;
$pointer = /$variable;
$ice = "jello";
$iceptr = /$ice;
引用$pointer指向$variavle的值位置,引用$iceptr指向"jello",即使$varivle销毁,仍然可以使用$pointer访问该值,这是一个硬引用,所以必须同时销毁$pointer和$variavle以便释放空间。
例子中引用变量$pointer保存的是$variavle的地址,而不是值本身,若要获取的其值,则用两个$$符号
e.g.
$value = 10;
$pointer = /$value;
printf "$$pointer";
2) 引用和数组
$pointer = /@ARGV
$i = 0;
foreach (@$pointer) {
print "$i: $$pointer[$i++]/n";
}
通过引用访问哈西表的形式为$$pointer{$index}($index为哈西表键值),构造哈西表还可以用=>符号:
%weekday = {
'01' => 'Mon',
'02' => 'Tue',
...
};
使用哈西表和数组时,用$和用->是等效的:
$$name[0] = "kamran";
等效于
$name->[0] = "kamran";
$$lastnames{"kamran"} = "Husain";
等效于
$lastnames->{"kamran"} = "Husain";
3) 子程序的引用
$pointer_to_sub = sub {... declaration of sub ...};
调用函数指针
&$pointer_to_sub(parameters);
4)文件句柄的引用
/*FILEHANDLE
e.g.
splitOut(/*STDIN);
splitOut(/*LPHANDLE);
十一、面向对象
十二、包和模块