探索Perl的世界(463.com:更新到40集)-Perl视频教程

Perl
的相比起来还是少.看视频,在入门时还是相当方便的,就象电影来看就好了。我基本
Superor 老师每出一集我都看了。希望大家也认真看看。

 

记的,学习时要多写,只能看明白,只有 5% 是你的,练习都做一做,就有 30%
是你的啦。其它的如果能根据教程,自己写出自己要的程序,才 80% 是你的.

标量

标量是 Perl 中最简单的数据类型。大多数的标量是数字(如 255 或
3.25e20)或者字符串(如 hello或者盖茨堡地址)。

再次感谢 Superor 老师.

数字

perl中所有数字内部的格式都是双精度浮点数。

注意下面的内容,如果加 .zip 可以直接下载的。
例如:http://www.boobooke.com/v/bbk2869.zip

浮点数

1.25
255.000
255.0
7.25e45 #7.25x10 的 45 次方(一个大整数)
-6.5e24 # -6.5x10 的 24 次方(一个大的负数)
-12e-24 #- -12x10 的-24 次方(很小的负数)
-1.2E-23 #指数符号可以大写(E)

第1集:第一章 Perl的概述
http://www.boobooke.com/v/bbk2869

整数

0
2001
-40
255
61298040283768

其中 61298040283768 也可以写作:

61_298_040_283_768

第2集:第二章 Perl的简单变量
http://www.boobooke.com/v/bbk2969

非十进制整数

0377 #八进制数字 377,等同于十进制数字 255
0xff #十六进制数字 FF,等同于十进制数字 255
0b11111111 #等同于十进制数字 255

可以用下划线表示:

0x1377_0B77
0x50_65_72_7C

第3集:第二章 Perl的字符串变量
http://www.boobooke.com/v/bbk3074

数字操作符

2+3 #2+3,5
5.1-2.4 #5.1-2.4,2.7
3*12 #3*12,36
14/2 #14/2,7
10.2/0.3 #10.2/0.3,34
10/3 #通常是浮点除,3.33333... ...

第4集:第二章 字符串变量和小结

字符串

http://www.boobooke.com/v/bbk3195

第5集:第三章 perl中的运算符
http://www.boobooke.com/v/bbk3335

第6集:第三章 perl中的运算符
http://www.boobooke.com/v/bbk3370

第7集:第三章 perl中的运算符优先级

单引号字符串

'fred' #四个字符:f,r,e,d
'' #空字符(没有字符)
'hello\n'
'\'\\' #单引号(')跟着反斜线(\)字符串

单引号中的 “\n” 不会被当作换行符来处理。

http://www.boobooke.com/v/bbk3403

第8集:第四章 perl中的控制结构
http://www.boobooke.com/v/bbk3428

第9集:第四章 perl中的控制结构

双引号字符串

"barney" #等同于 'barney'
"hello world\n" #hello world,换行

http://www.boobooke.com/v/bbk3448

第10集:第五章 列表与数组
http://www.boobooke.com/v/bbk3529

第11集:第五章 列表与数组
http://www.boobooke.com/v/bbk3530

第12集:第五章 列表与数组

字符串操作符

http://www.boobooke.com/v/bbk3531

第13集:第六章 关联数组
http://www.boobooke.com/v/bbk3600

第14集:第六章 关联数组
http://www.boobooke.com/v/bbk3601

第15集:第六章 关联数组

链接操作符 “.”
"hello"."world" # 同于 "helloworld"
"hello".''."world" # 同于 "hello world"
'hello world'."\n" # 同于 "hello world\n"

http://www.boobooke.com/v/bbk3602

第16集:第七章 文件
http://www.boobooke.com/v/bbk3681

第17集:第七章 文件
http://www.boobooke.com/v/bbk3682

第18集:第七章 文件
http://www.boobooke.com/v/bbk3683

第19集:第七章 文件

重复操作符 “x”
"fred" x 3 # "fredfredfred"
5 x 4 # 等于 "5" x 4, "5555"

http://www.boobooke.com/v/bbk3684

第20集:第八章 正则表达式
http://www.boobooke.com/v/bbk3748

第21集:第八章 正则表达式
http://www.boobooke.com/v/bbk3749

第22集:第八章 正则表达式
http://www.boobooke.com/v/bbk3750

第23集:第八章 正则表达式
http://www.boobooke.com/v/bbk3751

第24集:第八章 正则表达式

数字和字符串之间的自动转换

大多数情况下,Perl
将在需要的时候自动在数字和字符串之间转换。它怎样知道什么时候需要字符串,什么时候需要数字呢?这完全依赖于标量值之间的的操作符。如果操作符(如+)需要数字,Perl
将把操作数当作数字看待。如果操作符需要字符串(如 . ), Perl
将把操作数当作字符串看待。不必担心数字和字符串的区别;使用恰当的操作符,Perl
将为你做剩下的事。

"12" * "3" # * 操作符需要数字,所以结果为 36
"12fred34" * " 3" # 结果仍然是 36 , 后面的非数字部分和前面的空格都过滤掉。

"Z" . 5 * 7 # 等于 "Z".35,或 "Z35"

http://www.boobooke.com/v/bbk3752

第25集:第九章 格式化输出
http://www.boobooke.com/v/bbk3784

第26集:第九章 格式化输出

Perl 内嵌的警告

使用 -w 参数可以打开警告:

$ perl -w perl程序 # 命令行执行警告
#!/usr/bin/perl -w # 源代码中使用警告

http://www.boobooke.com/v/bbk3785

第27集:第十章 函数
http://www.boobooke.com/v/bbk3799

第28集:第十章 函数
http://www.boobooke.com/v/bbk3800

第29集:第十章 函数

标量变量

标量变量可以存放一个标量值。标量变量的名字由一个美圆符号($)后接 Perl
标识符:由字母或下划线开头,后接字母,数字,或者下划线。或者说由字母,数字和下划线组成,但不能由数字开头。大小写是严格区分的:变量$Fred
和变量$fred是不同的。任意字母,数字,下划线都有意义,如:

$a_very_long_variable_that_ends_in_1
$a_very_long_variable_that_ends_in_2

http://www.boobooke.com/v/bbk3801

第30集 第十一章 Perl引用
http://www.boobooke.com/v/bbk3851

第31集 第十一章 Perl引用
http://www.boobooke.com/v/bbk3852

第32集 第十一章 Perl引用
http://www.boobooke.com/v/bbk3853

第33集 第十一章 Perl引用

标量赋值

$fred = 17;
$barney = "hello";
$barney = $fred + 3;# 将$fred 的值加上三赋给$barney (20)
$barney= $barney*2;#将变量$barney 乘 2 再赋给$barney (40)

http://www.boobooke.com/v/bbk3854

第34集 第十二章 Perl包和模块
http://www.boobooke.com/v/bbk3915

第35集 第十二章 Perl包和模块
http://www.boobooke.com/v/bbk3916

第36集 第十二章 Perl包和模块

二元赋值操作符

$fred = $fred + 5; #没有用二元赋值操作符
$fred+=5; #利用二元赋值操作符
$barney = $barney*3;
$barney*=3;
$str = str . ""; #$str 后接空格;
$str .= ""; #同上

http://www.boobooke.com/v/bbk3917

第37集 第十三章 类和对象
http://www.boobooke.com/v/bbk3992

第38集 第十三章 类和对象
http://www.boobooke.com/v/bbk3993

第39集 第十三章 类和对象
http://www.boobooke.com/v/bbk3994

第40集 第十三章 类和对象
http://www.boobooke.com/v/bbk3995

print 输出

print "hello world\n"; #输出 hello world,后接换行符
print "The answer is", 6*7, ".\n"

字符串中引用标量变量

$meal = "brontosaurus steak" ;
$barney = "fred ate a $meal";
$barney = 'fred ate a'.$meal; # 同上

if 控制结构

if ($name gt 'fred') {
print "$name’comes after 'fred' in sorted order.\n";
}

Boolean 值

perl 没有专门的 Boolean 值,真假值这样判断:

  • 如果值为数字,0 是 false;其余为真
  • 如果值为字符串,则空串(‘)为 false;其余为真
  • 如果值的类型既不是数字又不是字符串,则将其转换为数字或字符串后再利用上述规则

这些规则中有一个特殊的地方。由于字符串’0′ 和数字 0 有相同的标量值,Perl
将它们相同看待。也就是说字符串 ‘0’ 是唯一一个非空但值为 0 的串。

用户的输入 <STDIN>

chomp 操作

$text = "a line of text\n"; # 也可以由<STDIN>输入
chomp($text); #去掉换行符(\n)。

一步执行:

chomp ($text = <STDIN>); #读入,但不含换行符

chomp
是一个函数。作为一个函数,它有一个返回值,为移除的字符的个数。这个数字基本上没什么用:

$food = <STDIN>;
$betty = chomp $food; #得到值 1

如上,在使用 chomp 时,可以使用或不使用括号()。这又是 Perl
中的一条通用规则:除非移除它们时含义会变,否则括号是可以省略的。

while 控制结构

$count = 0;
while ($count < 10) {
$count + = 2;
print "count is now $count\n";
}

undef 值

463.com,变量被赋值之前使用它会有什么情况发生呢?通常不会有什么严重的后果。变量在第一次赋值前有一个特殊值
undef, 按照 Perl
来说就是:”这里什么也没有,请继续”。如果这里的“什么也没有”是一些“数字”,则表现为
0。如果是“字符串”,则表现为空串。但 undef
既非数字也非字符串,它是另一种标量类型。

defined 函数

能返回 undef
的操作之一是行输入操作,<STDIN>。通常,它会返回文本中的一行。但如果没有更多的输入,如到了文件的结尾,则返回
undef。要分辨其是 undef 还是空串,可以使用 defined 函数, ,如果其参数是
undef 值就返回 false,其他值返回 true。

$madonna = <STDIN>;
If ($defined ($madonna)){
print "The input was $madonna";
} else {
print "No input available!\n;
}

如果想声明自己的 undef 值,可以使用 undef:

$madonna = undef ; #同$madonna 从未被初始化一样。

列表和数组

#!/usr/bin/env perl -w
$fred[0] = "yabba";
$fred[1] = "dabba";
$fred[2] = "doo";
print @fred;
#print @fred."\n";

qw 简写

qw ! fred barney betty wilma dino !
qw# fred barney betty wilma dino # #有些像注释
qw( fred barney betty wilma dino )
...

列表赋值

($fred, $barney, $dino) = ("flintstone", "rubble", undef);
($fred, $barney) = qw <flintstone rubble slate granite>; #两个值被忽略了
($rocks[0],$rocks[1],$rocks[2],$rocks[3]) = qw/talc mica feldspar quartz/;

当想引用这个数组时, Perl 有一种简单的写法。在数组名前加@(后没有中括号)
来引用整个数组。你可以把他读作 “all of the “(所有的)”,所以@rocks
可以读作 “all of the rocks(所有的石头)”。其在赋值运算符左右均有效:

@rocks = qw / bedrock slate lava /;
@tiny = (); #空表
@giant = 1..1e5; #包含 100,000 个元素的表
@stuff = (@giant, undef, @giant); #包含 200,001 个元素的表
@dino = "granite";
@quarry = (@rocks, "crushed rock", @tiny, $dino);

pop 和 push 操作

@array = 5..9;
$fred = pop(@array); #$fred 得到 9,@array 现在为(5,6,7,8)
$barney = pop @array; #$barney gets 8, @array 现在为(5,6,7)
pop @array; #@array 现在为(5,6)(7 被丢弃了)

push(@array,0); #@array 现在为(5,6,0)
push @array,8; #@array 现在为(5,6,0,8)
push @array,1..10; #@array 现在多了 10 个元素
@others =qw/9 0 2 1 0 /;
push @array,@others; #@array 现在又多了 5 个元素(共有 19 个)

shift 和 unshift 操作

push 和 pop
对数组的末尾进行操作(或者说数组右边有最大下标的元素,这依赖于你是怎样思考的)。相应的,
unshift 和 shift 对一个数组的开头进行操作(数组的左端有最小下标的元素)
。下面是一些例子:

@array = qw# dino fred barney #;
$m = shift (@array); #$m 得到 "dino", @array 现在为 ("fred", "barney")
$n = shift @array; #$n 得到 "fred", @array 现在为 ("barney")
shift @array; #@array 现在为空
$o = shift @array; #$o 得到 undef, @arry 仍为空
unshift(@array,5); #@array 现在为(5)
unshift @array,4; #@array 现在为(4,5)
@others = 1..3;
unshift @array, @others; #array 现在为(1,2,3,4,5)

和 pop 类似,如果其数组变量为空,则返回 undef。

字符串中引用数组

和标量类似,数组也可以插入双引号的字符串中。插入的数组元素会自动由空格分开:

@rocks = qw{ flintstone slate rubble };
print "quartz @rocks limestone\n"; #输出为 5 种 rocks 由空格分开

foreach 控制结构

foreach $rock (qw/ bedrock slate lava /) {
print "One rock is $rock.\n" ; #打印出 3 种 rocks
}

这里的$rock不是这些列表元素中的一个拷贝而是这些元素本身

最常用的默认变量: $_

如果在 foreach 循环中省略了控制变量,那 Perl
会使用其默认的变量:$_。除了其不寻常的名字外,这和普通变量类似,如下面代码所示:

foreach(1..10){ #使用默认的变量$_
print "I can count to $_!\n";
}

$_ = "Yabba dabba doo\n";
print; # 打印出默认变量 $_

reverse 操作

reverse(逆转)操作将输入的一串列表(可能是数组)按相反的顺序返回。

@fred = 6 .. 10;
@barney = reverse (@fred); #得到 10,9,8,7,6
@wilma = reverse 6 . .10; #同上,没有使用额外的数组
@fred = reverse @fred; #将逆转过的字符串存回去

sort 操作

@rocks = qw/ bedrock slate rubble granite /;
@sorted = sort(@rocks); #得到 bedrock, granite, rubble, slate

标量和列表上下文

42 + something #something 必须是标量
sort something #something 必须是列表

@people = qw( fred barney betty );
@sorted = sort @people; #列表内容: barney , betty, fred
$number = 42 + @people; #标量内容:42+3,得到 45

另一个例子是 reverse。在列表 context 中,它返回反转的列表。在标量 context
中,返回反转的字符串(或者将反转的结果串成一个字符串):

@backwards = reverse qw / yabba dabba doo /;
#返回 doo, dabba, yabba
$backwards = reverse qw/ yabba dabba doo /;
#返回 oodabbadabbay

在列表 Context 中使用 Scalar-Producing 表达式

如果一个表达式不是列表值,则标量值自动转换为一个元素的列表:

@fred = 6*7;
@barney = "hello" . '' . "world";

强制转换为标量 Context

偶尔,你可能需要标量 context 而 Perl
期望的是列表。这种情况下,可以使用函数
scalar。它不是一个真实的函数因为其仅是告诉 Perl 提供一个标量 context:

@rocks = qw(talc quartz jade obsidian);
print "How many rocks do you have?\n;
print "I have " @rocks, "rocks!\n"; # 错误,输出 rocks 的名字
print "I have " scalar @rocks, "rocks!\n; # 正确,输出其数字

<STDIN> 在列表 Context 中

@lines = <STDIN>; #将输入读入列表 context 中
chomp (@lines = <STDIN>); #读入所有的行,不包括换行符

子程序

使用 sub 定义子程序

sub marine {
$n + = 1; #全局变量$n
print "Hello, sailor number $n!\n";
}

调用子程序

&marine; #输出 Hello, sailor number 1!
&marine; #输出 Hello, sailor number 2!
&marine; #输出 Hello, sailor number 3!
&marine; #输出 Hello, sailor number 4!

通常有括号,即便参数为空。子程序将继承调用者的 @_ 的值。

参数

$n = &max(10,15); # 此子程序有 2 个参数

此参数列表被传到子程序中;这些参数可以被子程序使用。当然,这些参存放在某个地方,在
Perl
中,会自动将此参数列表(此参数列表的另一个名字)自动存放在一个叫做@_的数组中。子程序可以访问次数组变量来确定此参数的个数以及其值。这也就是说此子程序参数的第一个值存放在$_[0]中,第二个存放在$_[1](http://jianlee.ylinux.org/Computer/Perl/perl_base.html#fn.1),依次类推。但必须强调的是这些变量和
$_
这个变量没有任何关系,如$dino[3](http://jianlee.ylinux.org/Computer/Perl/perl_base.html#fn.3)(数组
@dino 的一个元素)和$dino 的关系一样。这些参数必须存放在某个数组变量中,
Perl 存放在@_这个变量中。

 sub max{
if($_[0] > $_[1]) {
$_[0];
} else {
$_[1];
}
}

my 变量

foreach (1..10){
my($square) = $_*$_; #本循环中的私有变量
print "$_ squared is $squrare.\n";
}

变量$square 是私有的,仅在此块中可见;在本例中,此块为 foreach 循环块。

当然,my 操作不会改变赋值参数的 context:

my ($num) = @_; # 列表 context, 同($sum) = @_;
my $num = @_; # 标量 context,同$num = @_;

使用 strict Pragma

use strict; #迫使采用更严格的检测

省略 &

有些地方调用子程序可以不要&

my @cards = shuffle(@deck_of_cards); # &是不必要的

输入和输出

从标准输入设备输入

从标准输入设备输入是容易的。使用<STDIN>。在标量 context
中它将返回输入的下一行:

$line = <STDIN>; #读入下一行;
chomp($line); #去掉结尾的换行符
chomp($line=<STDIN>) #同上,更常用的方法

于,行输入操作在到达文件的结尾时将返回
undef,这对于从循环退出时非常方便的:

while (defined($line = <STDIN>)) {
print "I saw $line";
}

从 <> 输入

尖括号操作(<>)是一种特殊的行输入操作。其输入可由用户选择

$n = 0;
while (defined($line = <>)) {
$n += 1;
chomp($line);
print "$n $line\n";
}

while (<>) {
chomp;
print "It was $_ that I saw!\n";
}

调用参数

技术上讲,<>从数组@ARGV 中得到调用参数。这个数组是 Perl
中的一个特殊数组,其包含调用参数的列表。换句话说,这和一般数组没什么两样
(除了其名字有些特别: 全为大写字母) ,程序开始运行时,调用参数已被存在@ARGV
之中了。

输出到标准输出设备

print @array; #打印出元素的列表
print "@array"; #打印一个字符串(包含一个内插的数组)

第一个语句打印出所有的元素,一个接着一个,其中没有空格。第二个打印出一个元素,它为@array
的所有元素,其被存在一个字符串中。也就是说,打印出@array
的所有元素,并由空格分开。如果@array 包含 qw /fred barney betty
/,则第一个例子输出为:fredbarneybetty,而第二个例子输出为 fred barney
betty(由空格分开)。

使用 printf 格式化输出

printf "Hello, %s : your password expires in %d days!\n",
$user, $days_to_die;
printf "%6f\n" 42; # 输出为 ○○○○ 42 (○此处指代空格)
printf "%23\n",2e3+1.95; # 2001

数组和 printf

my @items = qw( wilma dino pebbles );
my $format = "The items are:\n". ("%10s\n" x @items);
printf $format, @items;

等同:

printf "The items are:\n". ("%10s\n"x @items), @items;

本处 @items 有两个不同的 context
(上下文),第一次表示元素个数,第二次表示列表中的所有元素。

句柄(即文件描述符)

Perl 自身有六个文件句柄: STDIN,STDOUT,STDERR,DATA,ARGV,ARGVOUT

文件句柄的打开

open CONFIG, "dino" ;
open CONFIG, "<dino" ;
open BEDROCK, ">fred" ;
open LOG, ">>logfile" ;

Perl 的新版本中(从 Perl5.6 开始),open 支持“3 参数”类型:

open CONFIG, "<", "dino";
open BEDROCK, ">", $file_name;
open LOG, ">>", &logfile_name();

Bad 文件句柄

关闭文件句柄

close BEDROCK;

严重错误和 die

可以和 C 中使用 perror 类似,用 die 函数:

if (!open LOG, ">>logfile") {
die "Cannot create logfile:$!";
}

使用文件句柄

if (!open PASSWD, "/etc/passwd") {
die "How did you get logged in?($!)";
}
while (<PASSWD>) {
chomp;
...
}

哈希

什么是哈希

和 Python 的字典一样

哈希元素的存取

$hash {$some_key}

作为整体的 hash

要引用整个 hash,使用百分号(“%” )作为前缀。

%some_hash = ("foo",35, "bar", 12.4, 2.5, "hello", "wilma", 1.72e30, "betty", "bye\n");

hash 的值(在列表 context 中)是一个 key/value 对的列表:

@array_array = %some_hash;

哈希赋值

%new_hash = %old_hash;
%inverse_hash = reverse %any_hash;

大箭头符号 (=>)

my %last_name = (
"fred” => "flintstone",
"dino" => undef,
"barney" => "rubble",
"betty" => "rubble",
);

哈希函数

keys 和 values

my %hash = ("a" => 1, "b" => 2, "c" => 3);
my @k = keys %hash;
my @v = values %hash;

each 函数

while (($key, $value) = each %hash) {
print "$key => $value\n";
}

exists 函数

if (exists $books{$dino}) {
print "Hey, there's a libaray card for dino!\n";
}

delete 函数

my $person = "betty";
delete $books{$person}; # 将$person 的借书卡删除掉

正则表达式

简单的模式

$_ = "yabba dabba doo";
if (/abba/) {
print "It matched!\n";
}

所有在双引号中的转义字符在模式中均有效,因此你可以使用 /coke\tsprite/ 来匹配
11 个字符的字符串 coke, tab(制表符),sprite。

元字符

.
?
+
*

模式中的分组

/fred+/ # 只能匹配 fredddddd 等
/(fred)+/ # 能匹配 fredfredfred 等
/(fred)*/ # 可以匹配 "hello,world",因为 * 是匹配前面的 0或多次

选择符 (|)

/fred|barney|betty/
/fred( |\t)+barney/

字符类

指[]中的一列字符。

字符类的简写
\d == [0-9]
\w == [A-Za-z0-9_]
\s == [\f\t\n\r] # 格式符(form-feed)、制表符(tab)、换行符、回车
简写形式的补集
\D == [^\d]
\W == [^\w]
\S == [^\s]

可以组合:

[\d\D] # 任何数字和任何非数字,可以匹配所有字符!比如 . 是不能匹配所有字符的
[^\d\D] # 无用

正则表达式的应用

使用 m// 匹配

同 qw // 一样,可以使用任何成对字符,比如可以使用 m(fred),
m<fred>, m{fred}, m[fred],或者 m,fred,, m!fred!, m^fred^。

如果使用 / 作为分隔符,可以省略前面的 m

如果使用配对的分隔符, 那不用当心模式内部会出现这些分隔符,
因为通常模式内部的分隔符也是配对的。因此, m(fred(.*)barney),
m{\w{2,}}, m[wilma[\n
\t]+betty]是正确的。对于尖括号(<和>),它们通常不是配对的。如模式
m{(\d+)\s*>=?\s*(\d+)},如果使用尖括号,模式中的尖括号前因当使用反斜线(\),
以免模式被过早的结束掉。

相关文章