第一章 Perl 概述

来源:互联网 发布:麒麟linux官网 编辑:程序博客网 时间:2024/05/21 06:52
<pre name="code" class="sql">zjzc01:/root/big# cat a1.pl $camels = '123';print $camels + 1,"\n";zjzc01:/root/big# perl a1.pl 124$fido = new Camel "Amelia";if (not $fido){die "dead camel";}$fido->saddle();在这里,我们首选创建一个指向Camel对象的引用,并将它赋给变量$fido,在第二行中,我们将$fido当成一个布尔值来判断它是否为真,如果它不为真,程序将抛出一个异常。在这个例子中,这意味着new Camel 构造器创建Camel对象失败。最后一行,我们将$fido作为一个引用,并调用Camel对象的saddle()方法。@home=("counch","chair","table","stove");[root@master Webqq]# cat k1.pl @home=("counch","chair","table","stove",1,2,3,4,5);print "\@home is @home\n";($a,$b,$b,$c,$d)=@home;print "\$a is $a\n";print "\$b is $b\n";print "\$c is $c\n";print "\$d is $d\n";[root@master Webqq]# perl k1.pl @home is counch chair table stove 1 2 3 4 5$a is counch$b is table$c is stove$d is 1() 小括号 数组{} 大括号  hash数据元素读取:[root@master Webqq]# cat k5.pl @a=qw/4 7 1 3/;print "\$a[1] is $a[1]\n";[root@master Webqq]# perl k5.pl $a[1] is 7hash 元素读取:[root@master Webqq]# cat k6.pl %hash=(a=>1,b=>5,c=>100);print $hash{b};[root@master Webqq]# perl k6.pl 5[root@master Webqq]# spili 操作符:[root@master ~]# cat p1.pl ($a,$b,$c)=split(/,/,"vi,edit,plus");print "\$a is $a\n";print "\$b is $b\n";print "\$c is $c\n";[root@master ~]# perl p1.pl $a is vi$b is edit$c is plus=~  模式绑定操作符读取控制台输入:[root@master ~]# cat p2.pl while ($line =<>){   if ($line =~/http/){print "\$line is $line\n"}}[root@master ~]# perl p3.pl httpftp[root@master ~]# cat p3.pl open (FILE,"<","a.txt") or die $!;while (<FILE>){  print if /http/i;  print if /ftp/i;  print if /ssh/i;}+是一个特殊字符,表位匹配+前面的内容一次或多次. 点号 匹配所有的字符,除换行符外  * 表示0次或多次?表示零次或一次空白     [\t\n\r\f]     \s调字符   [a-zA-Z_0-9]   \w数字      [0-9]         \d最小匹配 非贪婪匹配在新版本的Perl中,可以强制进行非贪婪匹配。在量词后面加上一个问号来表示最小匹配。单词边界:特殊符号\b 匹配单词边界,就是位于单词字符(\w)和非单词字符(\W)之间的零宽度的地方(字符串的开始和结尾被认为是非单词字符).例如:反向引用:我们曾经提到过用小括号来为量词包围一些字符,同样,也可以使用小括号来记住匹配到的东西。正则表达式中的一对小括号使得这部分匹配到的定西将被记住,以供以后使用。[root@master Webqq]# cat t9.pl while (@ARGV){    print "\@ARGV is @ARGV\n";    shift @ARGV;};[root@master Webqq]# perl t9.pl  1 2 3 4 5@ARGV is 1 2 3 4 5@ARGV is 2 3 4 5@ARGV is 3 4 5@ARGV is 4 5@ARGV is 5\b 匹配单词边界,就是位于单词字符(\w)和非单词字符(\W)之间的零宽度的地方。(字符串的开始和结尾也被认为是非单词字符)  例如: /\bFred\b/ 将会匹配"The Great Fred"和"Fred the Great"中的Fred,但不能匹配"Frederick the Great", 因为在"Fredrick"中的"d"后面没有跟着非单词字符数组和散列也互不相同,当你想通过编号来查找东西的时候,你要用数组。而如果你想通过名称来查找东西,那么你应该用散列。散列,散列时一组无序标量,散列经常被称为关联数组,没有顺序1.2.4 复杂的数据结构:[] 表示数组的引用:$wife{"Jacob"} = ["Leah","Rache;","Bilhah","Zilaah"];这个语句创建了一个未命名的数组,并将这个数组的引用放入散列的元素$wife{"jacob"};zjzc01:/root/big# cat a2.pl $wife{"Jacob"} = ["Leah","Rache;","Bilhah","Zilaah"];print $wife{"Jacob"}[0]; print "\n";zjzc01:/root/big# perl a2.pl Leahzjzc01:/root/big# cat a3.pl $kids_of_wife{"Jacob"}={    "Leah" => ["Reuben","Simeon","Levi","Judah","Issachar","Zebulun"],    "Rachel" => ["Joseph","Benjamin"],    "Bilhah" => ["Dan","Naphtali"],    "Zilpah" => ["Gad","Asher"]};print $kids_of_wife{"Jacob"}{"Leah"}[0];print "\n";zjzc01:/root/big# perl a3.pl Reuben1.2.5  简单数据结构:Perl 也有一些主题化的方法,最主要的就是使用package声明。例如你想在Perl中讨论Camels,你会在Camel模块中以下面的方法开头:package Camel;这个开头有几个值得注意的效果,其中之一就是从这里开始,Perl认为所有没有特别指出的动词和名次都是关于Camels的,Perl 通过在全局名字前添加模块名字"Camel::"来实现。因此当你使用下面的方法:package Camel;package Dog;$fido = &fetch();这里的$fido 的真实名字是$Camel::fido( &fetch 的真实名字是&Camel::fetch)当我们使用:$fido = new Camel "Amelica";我们实际上调用Camel 包中的&new,它的全名是&Camel::new.并且当我们使用:$fido->saddle();的时候,我们调用&Camel::saddle 过程,因为$fido 记得它是指向一个Camel对象的。zjzc01:/root/big# cat a5.pl $a=1;$a.=b;print $a;zjzc01:/root/big# perl a5.pl 1bzjzc01:/root/big# 因此a.=b 就相当于 把a 和b字符串的内容和并,存入aperl hash 累加,根据 $grades{$student}  累加次数zjzc01:/root/big# cat a5.pl open(GRADES, "grades") or die "Can't open grades: $!\n"; while ($line = <GRADES>) { ($student, $grade) = split(" ", $line);print "\$student is $student\n";print "\$grade is $grade\n"; $grades{$student} ++ ; };while(my($ip, $times) = each %grades) {                   print "$ip  ==   $times\n";};zjzc01:/root/big# cat grades A 70B 80C 90D 50E 60E 60E 60F 80zjzc01:/root/big# perl a5.pl F  ==   1A  ==   1D  ==   1C  ==   1E  ==   3B  ==   1-----------------------------------------------------------------perl 把文本内容转换为hash 数组:zjzc01:/root/big# cat grades A 70B 80C 90D 50E 60E 60E 60F 80zjzc01:/root/big# cat a6.pl open(GRADES, "grades") or die "Can't open grades: $!\n"; while ($line = <GRADES>) { ($student, $grade) = split(" ", $line); $grades{$student} .= $grade . " "; };print "\%grades  is :\n";print %grades;print "\n";print "\$grades{A} is $grades{A}\n";zjzc01:/root/big# perl a6.pl %grades  is :F80 A70 D50 C90 E60 60 60 B80 $grades{A} is 70 计算平均值:zjzc01:/root/big# cat grades A 70B 80C 90D 50E 60F 80zjzc01:/root/big# cat a6.pl open(GRADES, "grades") or die "Can't open grades: $!\n"; while ($line = <GRADES>) { ($student, $grade) = split(" ", $line); $grades{$student} .= $grade." " ; };print "\%grades  is :\n";print %grades;print "\n";print "\$grades{A} is $grades{A}\n";foreach $student (sort keys %grades){ $scores = 0; $total = 0; push (@grade,$grades{$student});};print "\@grade is @grade\n"; foreach $grade (@grade){$total +=$grade;$scores++};print "\$total is $total\n";print "\$scores is $scores\n";$average = $total / $scores;foreach $student (sort keys %grades){print "$student:$grades{$student}\tAverage :$average\n";}zjzc01:/root/big# perl a6.pl %grades  is :F80 A70 D50 C90 E60 B80 $grades{A} is 70 @grade is 70  80  90  50  60  80 $total is 430$scores is 6A:70 Average :71.6666666666667B:80 Average :71.6666666666667C:90 Average :71.6666666666667D:50 Average :71.6666666666667E:60 Average :71.6666666666667F:80 Average :71.6666666666667zjzc01:/root/big# cat grades A 70B 80C 90D 50E 60F 80zjzc01:/root/big# cat a7.pl open(GRADES, "grades") or die "Can't open grades: $!\n"; while ($line = <GRADES>) { ($student, $grade) = split(" ", $line); $grades{$student} = $grade ; };print "\%grades  is :\n";print %grades;print "\n";print "\$grades{A} is $grades{A}\n";print "\n";print "\$grades{B} is $grades{B}\n";zjzc01:/root/big# perl a7.pl %grades  is :F80A70D50C90E60B80$grades{A} is 70$grades{B} is 80chop 不加区别地去掉字符串最后一个字符,并将结果返回chomp 仅删除结束标记(通常是"\n")改变hash 数组的值:zjzc01:/root/big# cat a8.pl %hash=("a"=>1,"b"=>2,"c"=>3);print %hash;print "\n";print "\$hash{a} is $hash{a}\n";$hash{a}=99;print %hash;print "\n";zjzc01:/root/big# perl a8.pl c3a1b2$hash{a} is 1c3a99b21.除了""和"0",所有字符串为真2.除了0, 所有数字为真3.所有引用为真4.所有未定义的值为假。zjzc01:/root/big# cat a9.pl $city='Miami';if ($city eq "New York"){   print "1111111111\n";}elsif ($city eq "Chicago"){  print "22222222222\n";}elsif ($city eq "Miami"){ print "333333333333\n";}else {print "444444444\n"}zjzc01:/root/big# perl a9.pl 3333333333331.6.3.4 跳出控制结构:next 和last:next和last 操作符允许你在循环中改变程序执行的方向,你可能会经常遇到一些的特殊情况,碰到这种情况时你希望跳过它,或者想退出循环。next 操作符允许你将跳至本次循环的结束,开始下一次循环:zjzc01:/root/big# cat a10.pl for ($i=1;$i<=3;$i++){    print "\$i is $i\n";     open (LOG ,"<","tmp.out");                      while (<LOG>) {  chomp ;      if ($_ eq 'b'){next;};      print "$_ is $_\n"; }}  zjzc01:/root/big# perl a10.pl $i is 1a is ac is c$i is 2a is ac is c$i is 3a is ac is cnext 是跳过本次循环:last 退出循环:zjzc01:/root/big# cat a10.pl for ($i=1;$i<=3;$i++){    print "\$i is $i\n";     open (LOG ,"<","tmp.out");                      while (<LOG>) {  chomp ;      if ($_ eq 'b'){last;};      print "$_ is $_\n"; }}  zjzc01:/root/big# perl a10.pl $i is 1a is a$i is 2a is a$i is 3a is a因为正则表达式是一组字符串的抽象,我们可以只描述我们要找的东西:后面跟着一个冒号的一些字符。用正则表达式表示为/[a-zA-Z]+:/,这里方括弧定义了一个字符串,a-z和A-Z代表多有的字母字符(划线表示从开头的字符到结尾字符中间的所有字母字符)+ 是一个特殊字符,表示匹配前面内容一次或多次。 我们称之为量词,名字   ASCII 定义  代码空白  [\t\n\r\f]   \s词    [a-zA-Z_0-9]  \w还有一种非常特别的字符类型,用"." 来表示,这将匹配所有的字符。(注: 出了通常它不会匹配一个新行之外。1.7.1  量词:\d{7,11} 将匹配最少7位数字,但不会多于11位数字。如果在括弧中只有一个数字,这个数字就指定了最少和最多匹配次数,也就是指定了准确的匹配次数一些特殊的最少和最多地经常会出现, 因此Perl定义了一些特殊的运算符来表示他们。像我们看到过的+, 代表{1,}  意思为最少一次。还有*对于量词而言,你需要注意以下一些问题。首先,在缺省状态下,Perl量词都是贪婪的,也就是他们将尽可能多的匹配一个字符串中最大数量的字符,例如,如果你使用/\d+/来匹配字符串"1234567890",那么真这个表达式将匹配整个字符串。zjzc01:/root/big# cat a11.pl $_ = "fred xxxxxxx barney";s/x*//;print "\$_ is $_\n";zjzc01:/root/big# zjzc01:/root/big# zjzc01:/root/big# perl a11.pl $_ is fred xxxxxxx barneyzjzc01:/root/big# 但是上面的代码并没有达到预想的目的,这是因为x*(表示零次或多次x)在字符串中开始匹配了空字符串,因为空字符串具有零字符宽度,并且在fred的f字符前正好有一个空字符串。1.7.2  最小匹配:在新版本Perl中,你可以强制进行非贪婪匹配。在量词后面加上一个问号来表示最小匹配,我们同样的用户名匹配就可以写成/.*?:/ 这里的.*? 现在尽可能少的匹配字符,而不是尽可能多的匹配字符。所以它将停止在第一个冒号而不是最后一个:特殊符号\b匹配单词边界,就是位于单词字符(\w) 和非单词字符(\W) 之间的零宽度的地方。(字符串的开始和结尾也被任务是非单词字符).例如:/\bFred\b/ 将会匹配"The Great Fred"和"Fred the Great"中的 Fred, 但不能匹配"Frederick the Great",因为在“Frederick the Great”中的"d" 后面没有跟着非单词字符。zjzc01:/root/big# cat a12.pl $_='Fred 1';if ($_ =~/\bFred\b/){print "1111111\n"};$_='Fred1';if ($_ =~/\bFred\b/){print "22222222\n"};zjzc01:/root/big# perl a12.pl 11111111.7.4  反引用:我们曾经提到过可以用圆括弧来为量词包围一些字符,同样,你可以使用圆括弧来记住匹配到的东西。正则表达式中的一对圆括弧使得这部分匹配到的东西将被记住以供以后使用。它不会改变匹配的方式,因此/\d+/ 和/(\d+)/ 仍然尽可能多地 匹配数字 但后边的写法能把匹配到的数字保存到一个特殊变量中,以供以后反向引用。1.8 列表处理:zjzc01:/root/big# cat a13.pl $_ = '12:59:59 am';if ($_ =~ /(\d{1,2}):(\d{1,2})*/){$hour=$1;$min=$2;$sec=$3;$ampm=$4;};print "\$hour is $hour\n";print "\$min is $min\n";zjzc01:/root/big# perl a13.pl $hour is 12


                                             
0 0