Perl 语言学习笔记

前言

这几天学习了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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值