文章目录
前言
这几天学习了Perl语言,为了在以后看不懂语法时方便快速查询,花了一下午时间整理下Perl语言关键的语法。我实在没有兴趣去深究这门语言😟,学习时大部分参考 [link]http://www.runoob.com/perl/perl-tutorial.html 上的教程,本文的大部分内容也是来自这个网站。
附:[Perl官方文档] http://perldoc.perl.org/index.html 。
Perl语法
Perl 基础语法
- 每条语句以分号
;
结束 - 输出字符串可以使用单引号
'
和双引号"
,双引号中的字符会进行转义输出,单引号中的字符不会。
print "Hello, world\n"; # 双引号
print 'Hello, world\n'; # 单引号
输出结果:
Hello, world
Hello, world\n
- Here 文档,一种定义字符串的方法。
$a = 10;
$var = <<"EOF";
这是一个 Here 文档实例,使用双引号。
可以在这输如字符串和变量。
例如:a = $a
EOF
print "$var\n";
会将<<"EOF"
开始到EOF
之间的所有字符都赋值给变量var
,输出的var
的值如下:
这是一个 Here 文档实例,使用双引号。
可以在这输如字符串和变量。
例如:a = 10
Perl 数据类型
标量
标量是Perl语言中最简单的一种数据类型。这种数据类型的变量可以是数字,字符串,浮点数,不作严格的区分。在使用时在变量的名字前面加上$
字符,表示是标量。例子如下:
$a = 123; # 数字 123
$b = 1.0; # 浮点数 1.0
$c = "123"; # 字符串 123
print "\$a = $a\n";
数组
数组是多个标量的顺序集合,类似于python中的list
类型。数组变量以@
字符开头,索引从0开始。例子如下:
@a = (1, 2, 3); # 整型数组
@b = qw/hello world/; # 通过qw//定义字符串数组,第一个元素为字符串'hello'
@var_10 = (1..10); # 数字1到10组成的数组
@var_5 = @var_10[0..4]; # 数字1到5组成的数组
# 数组变量通过索引引用
print "\@a[0] = $a[0]\n"; # 第一个元素,输出数字 1
print "\@b[0] = $b[0]\n"; # 第一个元素,输出字符串 hello
print "\@b[-1] = $b[-1]\n"; # 最后一个元素,输出字符串 world
print "\@var_10 = @var_10\n"; # 输出 1 2 3 4 5 6 7 8 9 10
print "\@var_5 = @var_5\n"; # 输出 1 2 3 4 5
# 获取数组大小
$size = @a; # 将数组变量赋值给标量,则标量的值为数组大小
print "\$size = $size\n"; # 输出数组物理大小 3, 而不是元素个数
添加和删除数组元素的操作如下:
操作 | 描述 |
---|---|
push @ARRAY, LIST | 将列表中的元素放到数组尾部。 |
pop @ARRAY | 弹出数组最后一个元素,并返回它。 |
shift @ARRAY | 弹出数组第一个元素,并返回它。 |
unshift @ARRAY, LIST | 将列表中的元素放到数组首部,并返回新数组的元素个数。 |
哈希
哈希是一个无序的key/value对集合,类似于python中的dict
类型。哈希变量以%
字符开头。例子如下:
# 初始化哈希,以下几种形式都可以
%a = ('a'=>1, 'b'=>2, 'c'=>3); # 推荐的形式
%b = ('a', 1, 'b', 2, 'c', 3);
%c = (-a=>1, -b=>2, -c=>3); # 居然还有这种形式。。无语。。
%d = (a=>1, b=>2, c=>3);
# 引用哈希
print "\$a{'a'} = $a{'a'}\n"; # 注意是 $a{'a'},而不是 %a{'a'}!!!
print "\$b{'b'} = $b{'b'}\n";
print "\$c{-c} = $c{-c}\n";
print "\$d{c} = $d{c}\n";
# 提取哈希的多个值到数组
@a1 = @a{'a', 'b'}; # 注意是 @a{'a', 'b'},而不是 %a{'a', 'b'}!!!
@keys = keys %a; # 提取哈希所有的键
@values = values %a; # 提取哈希所有的值
$size = @keys; # 哈希大小
print "\@a1 = @a1\n";
print "\@values = @values\n";
print "\@keys = @keys\n";
print "\$size = $size\n";
# 添加元素 # 注意是 $a{'d'},而不是 %a{'d'}!!!
$a{'d'} = 4;
# 删除元素
delete $a{'d'};
注意:引用数组或哈希中的单个元素都是在数组或哈希变量前使用前缀$
,因为数组或哈希中的单个元素数据类型是标量。在perl语言中,类似$
的前缀表示你想获取到的数据类型而不是已经获取到的数据类型。
将哈希嵌入到数组中或者其他哈希的值中要使用{}
符号。比如:
@a = (1,{1=>1,2=>2}); # 哈希嵌入数组a中
print "@a\n";
%a = (1=>{1=>1,2=>2}, 2=> 2); # 哈希嵌入到哈希a的值中
foreach my $key ( keys %a ){
my $value = $a{$key};
print "$key : $value\n";
}
输出:
1 HASH(0x1af2af8)
1 : HASH(0x1af2b40)
2 : 2
Perl 条件语句
if
语句。if...else
语句。if...elsif...else
语句。unless
语句。unless...else
语句。unless...elsif..else
语句。
unless
语句和if
语句执行条件相反,unless
语句在条件为false时执行。
Perl 循环
循环语句
while
循环。until
循环。for
循环。
如下是for循环一个特殊用法:
# 打印 1 到 10
for (1 .. 10) {
print "$_\n";
}
print "$_\n" for (1 .. 10);
foreach
循环。用于迭代一个数组。
@a = (1, 2, 3, 4, 5);
# 打印数组
foreach $a (@a){
print "$a\n";
}
# 打印数组
foreach (@a){
print "$_\n"; # $_是一个特殊变量
}
do...while
循环。
循环控制语句
next
语句。停止执行从next语句的下一语句开始到循环体结束标识符之间的语句,转去执行continue语句块,然后再返回到循环体的起始处开始执行下一次循环。
$a = 10;
while( $a < 20 ){
if( $a == 15)
{
# 跳出迭代
$a = $a + 1;
next;
}
print "a 的值为: $a\n";
$a = $a + 1;
}
输出:
a 的值为: 10
a 的值为: 11
a 的值为: 12
a 的值为: 13
a 的值为: 14
a 的值为: 16 # 没有打印 15
a 的值为: 17
a 的值为: 18
a 的值为: 19
last
语句。类似C语言的break语句。continue
语句。Perl continue 块通常在条件语句再次判断前执行。continue 语句可用在 while 和 foreach 循环中。
$a = 0;
while($a < 3){
print "a = $a\n";
}continue{
$a = $a + 1;
}
输出:
a = 0
a = 1
a = 2
redo
语句。直接转到循环体的第一行开始重复执行本次循环,redo语句之后的语句不再执行,continue语句块也不再执行。
$a = 0;
while($a < 10){
if( $a == 5 ){
$a = $a + 1;
redo;
}
print "a = $a\n";
}continue{
$a = $a + 1;
}
输出:
a = 0
a = 1
a = 2
a = 3
a = 4
a = 6 # 输出 6,说明没有执行continue语句
a = 7
a = 8
a = 9
goto
语句。类似C语言的goto语句。
Perl 运算符
只列出比较奇怪的地方。。
比较运算符
比较运算符除了如<
符号的形式外还可以是字符串的形式:lt
gt
le
ge
eq
ne
cmp
。如:
$a = 1;
$b = 2;
if ($a lt $b) {
print "$a < $b\n";
}
逻辑运算符
支持and
&&
or
||
not
!
这几种逻辑运算符。
and
和&&
都表示逻辑与。
or
和||
都表示逻辑或。
not
和!
都表示逻辑非。
引号运算
运算符 | 描述 | 实例 |
---|---|---|
q{ } | 为字符串添加单引号 | q{abcd} 结果为 ‘abcd’ |
qq{ } | 为字符串添加双引号 | qq{abcd} 结果为 “abcd” |
qx{ } | 为字符串添加反引号 | qx{abcd} 结果为 `abcd` |
其他运算符
运算符 | 描述 | 实例 |
---|---|---|
. | 用于连接两个字符串。 | $a="hello ", $b=“world” , $a.$b 结果为 “hello world”。 |
x | 将字符串重复一定次数。 | (’-’ x 3) 输出为 —。 |
.. | 范围运算符。 | (2…5) 输出结果为 (2, 3, 4, 5)。 |
-> | 箭号用于指定一个类的方法 | $obj->$a 表示对象 $obj 的 $a 方法。 |
Perl 函数
Perl函数用sub
关键字定义,语法如下:
sub fun{
......;
}
直接看一个求平均数函数的例子:
sub average{
my $n = scalar(@_);
my $sum = 0;
foreach my $i (@_){
$sum += $i;
}
return $sum / $n;
}
$average = average(1,2,3,4);
print "\$average = $average\n";
关于函数的几点说明:
- 传给函数的所有的参数在函数内部通过一个特殊变量
@_
获取。scalar(@_)
返回参数的个数。$_[0]
表示第一个参数,$_[1]
表示第二个参数等等。 - 函数中的变量前面都加了
my
关键字,如果不加这个关键字,会引用全局变量。 - 如果没有使用
return
语句,则子程序的最后一行语句将作为返回值。 - 需要将标量和数组(或哈希)同时当作参数传递给函数时,需要把数组(或哈希)放到最后。
sub test{
my ($a,@b) = @_;
print "$a\n";
print "@b\n";
}
test(1, (2,3,4));
test((2,3,4), 1);
输出:
1
2 3 4
2
3 4 1
- 函数会根据上下文来返回不同类型的值。
# 标量上下文
my $datestring = localtime( time );
print $datestring;
print "\n";
# 列表上下文
($sec,$min,$hour,$mday,$mon, $year,$wday,$yday,$isdst) = localtime(time);
printf("%d-%d-%d %d:%d:%d",$year+1990,$mon+1,$mday,$hour,$min,$sec);
print "\n";
输出:
Thu Sep 6 18:59:04 2018
2108-9-6 18:59:4
Perl 引用
引用就是指针,Perl 引用是一个标量类型,它可以指向变量、数组、哈希甚至函数,可以应用在程序的任何地方。定义变量的时候,在变量前加上\
字符,就得到了这个变量的一个引用。例子如下:
$ref = \$a; # 引用标量
print "$$ref\n"; #或${$ref}
$ref = \@ARGV; # 引用数组
print "@$ref\n"; #或@{$ref}
$ref = \%ENV; # 引用哈希
print "%$ref\n"; #或%{$ref}
$ref = \&average; # 引用函数
print "average = ",&$ref(1,2,3),"\n"; #或&{$ref}
# 引用匿名数组
$aref= [ 1,"foo",undef,13 ];
$bref = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
];
# 引用匿名哈希
$href = { APR =>4, AUG =>8 };
# 引用匿名函数
$coderef = sub { print "hello world!\n" };
# 引用匿名哈希
my $address = { "building" => 1000,
"street" => "ABC street",
"city" => "Headquarter",
"state" => "CA",
"zipcode" => 95134,
"country" => "USA"
};
print $address->{building};
print $address->{street};
Perl 错误处理
当打开一个文件失败时,打印出错误信息并退出程序的例子如下:
$file = '/tmp/123';
# 下面几种写法都是等价的
unless (open(DATA, $file)) {
die "Error: $!";
}
die "Error: $!" unless open(DATA, $file);
open(DATA, $file) || die "Error: $!";
open(DATA, $file) or die "Error: $!";
Perl 特殊变量
主要说下$_
特殊变量,以下是几处即使没有写明 ,Perl 也会假定使用 $_
的地方:
- 各种列表函数,例如
print()
和unlink()
。 - 没有使用
=~
运算符时的模式匹配操作m/.../
、s/.../.../
和tr/.../.../
。 - 在没有给出其他变量时是
foreach
循环的默认迭代变量。 grep()
和map()
函数的隐含迭代变量。
特殊变量太多了,直接参考[perdoc]http://perldoc.perl.org/perlvar.html 或
[link]http://www.runoob.com/perl/perl-special-variables.html 。
Perl 正则表达式
Perl 正则表达式的三种形式:
- 匹配:
m/.../
。这种情形下也可省略字母m,直接写成/.../
。 - 替换:
s/.../.../
- 转化:
tr/.../.../
这三种形式一般都和=~
或!~
搭配使用,=~
表示相匹配,!~
表示不匹配。
直接参考[link]http://www.runoob.com/perl/perl-regular-expressions.html 。
Perl 面向对象
面向对象基础概念
- 对象:对象是对类中数据项的引用。
- 类:类是个Perl包,其中含提供对象方法的类。
- 方法:方法是个Perl子程序,类名是其第一个参数。
类
- 一个类只是一个简单的包(package)。
- 可以把一个包当作一个类用,并且把包里的函数当作类的方法来用。Perl 的包提供了独立的命名空间,不同包的方法与变量名不会冲突。
- Perl 类的文件后缀为
.pm
。
直接看一个例子,一个Person类的代码如下:
package Person;
sub new
{
my $class = shift; #弹出第一个参数,即类名
my $self = {
_firstName => shift, #第二个参数
_lastName => shift, #第三个参数
_age => shift, #第四个参数
};
# 输出用户信息
print "名:$self->{_firstName}\n";
print "姓:$self->{_lastName}\n";
print "年龄:$self->{_age}\n";
bless $self, $class;
return $self;
}
sub setFirstName {
my ( $self, $firstName ) = @_;
$self->{_firstName} = $firstName if defined($firstName);
return $self->{_firstName};
}
sub getFirstName {
my( $self ) = @_;
return $self->{_firstName};
}
1;
使用该类的例子如下:
use Person;
$object = new Person( "小明", "王", 21);
# 调用方法获取姓名
$firstName = $object->getFirstName();
# 调用方法更改姓名
$object->setFirstName( "小强" );
Perl 常用函数
[use
] http://perldoc.perl.org/functions/use.html
[our
] http://perldoc.perl.org/functions/our.html
[my
] http://perldoc.perl.org/functions/my.html
[local
] http://perldoc.perl.org/functions/local.html
[defined
] http://perldoc.perl.org/functions/defined.html
[undef
] http://perldoc.perl.org/functions/undef.html
[bless
] http://perldoc.perl.org/functions/bless.html
[print
] http://perldoc.perl.org/functions/print.html
[die
] http://perldoc.perl.org/functions/die.html
[shift
] http://perldoc.perl.org/functions/shift.html
[unshift
] http://perldoc.perl.org/functions/unshift.html
[map
] http://perldoc.perl.org/functions/map.html
[grep
] http://perldoc.perl.org/functions/grep.html
[length
] http://perldoc.perl.org/functions/length.html
[substr
] http://perldoc.perl.org/functions/substr.html
[join
] http://perldoc.perl.org/functions/join.html
[pack
] http://perldoc.perl.org/functions/pack.html
[unpack
] http://perldoc.perl.org/functions/unpack.html
[open
] http://perldoc.perl.org/functions/open.html
[sysread
] http://perldoc.perl.org/functions/sysread.html
[syswrite
] http://perldoc.perl.org/functions/syswrite.html
[close
] http://perldoc.perl.org/functions/close.html
[select
] http://perldoc.perl.org/functions/select.html