perl笔记整理

1. 在Perl 中,注释由#开始,直到本行结束(Perl 中没有“块注释”(block comments))

   (1) 在Unix 系统中◆,如果文本的第一行前两个字符是“#!”,接着的就是执行下面文件的程序

#! /usr/bin/perl

print “Hello,word!\n”

  (2) 在非Unix 系统中,传统上把第一行写做#!perl。

 

2. s/\w<([^>]+)>/\U$1\g 能改变有特殊标记(<>)的行,在每一perldoc 这个命令的输出中,都至少有一行具有这样的形式。

  #! /usr/bin/perl

  @lines= `perldoc –u –f atan2`;

  foreach(@lines){

  s/\w<([^>]+)/\U$1/g;

  print;

  }

 

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

 

4. 操作符由两个*号表示,如2**3,表示2 的3 次方,等于8(操作符的优先级:右 <-- [\ ! ~ + - (一元操作符)],[?:(三元操作符)],[= += -= .=],[not])

 

5. 单引号字符串: 除了单引号,或者反斜线(包括换行字符,如果字符串在下一行继续)之外的任何字符都表示它自身

 

6. 双引号字符串: 双引号字符串另一个性质是可进行变量内插,这是说当使用字符串时,如果字符串中含有变量名,将由变量的当前值替换

 

7. 转义字符:

 \b 退格       

 \cC 一个控制符(这里是,ctrl +c)

 \l 下个字符小写(eg. \lSelina --> selina)

 \L 接着的字符均小写直到\E

 \u 下个字符大写

 \U 接着的字符均大写直到\E(eg. \lSel\Eina --> SELina)

 \E 结束\L,\E 和\Q

 

8. 字符串操作符

(1) 串联必须由. 操作符进行 ‘hello world’. “\n” #同于“hello world\n”

(2) 一个特殊的操作符是字符串重复操作符(string repetition operator),由小写的字母x 表示。这种操作能把操作符左边字符串

    重复操作符右边数字那么多次:"fred"x3 --> fredfredfred

    复制次数(右操作数)在使用之前会把它转换为小于等于它的整数(如,4.8 变为4)。重复次数小于1 将产生空串(长度

    为0)。

 

9. 数字和字符串之间的自动转换: 如“12fred34”* “3”将给出36。

   在极端情形,当一个不含任何数字的字符串将转换为0(eg. "fgfh" * 0.9 --> 0)

   

10. 标量变量的名字由一个美圆符号($)后接Perl 标识符:由字母,数字和下划线组成,但不能由数字开头。大小写是严格区分的:

变量$Fred 和变量$fred是不同的。任意字母,数字,下划线都有意义,如:

$a_very_long_variable_that_ends_in_1

 

11. 字符串中标量变量的内插:

 (1)当一个字符串由双引号括起来时,如果变量前没有反斜线,则变量会被其值内插。也就是说字符串中的标量变量将被其值替换。

 如果使用的是单独一个变量,是否使用引号没有影响。如:

 print “$fred”; #引号是没有必要的

 print $fred; #更好的写法

 (2)在字符串中变量前($符号前)加上反斜线(\),变量将不会被内插(替换)

 (3)Perl 在内插数组时,它会在元素之间加入空格

 

12. Perl 没有Boolean类型

● 如果值为数字,0 是false;其余为真

● 如果值为字符串,则空串(‘’)为false;其余为真

● 如果值的类型既不是数字又不是字符串,则将其转换为数字或字符串后再利用上述规则

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

一个非空但值为0 的串。

eg. 

 if ('0'){

  print "'$name' comes after 'fred' in sorted order.\n";

 }else{

  print"'$name' does not come after 'fred'.\n";

 }

 ==> '$name' does not come after 'fred'.

 

13. 列表是标量的有序集。数组是包含列表的变量。在Perl 中这个两个术语是可以互换的。但严格意义上讲,列表是指数据,

而数组是其变量名。可以有一些值(列表)但不属于数组;但每一个数组标量都有一个列表,虽然其可以为空

 列表中每一个元素都是一个独立的标量值.

 

14. 有时需要知道数组最后一个元素的索引。如:使用的rocks 数组,其最后一个元素的索引为$#rocks

 一种简便方法:数组的负数索引值从最后一个元素开始:有效的负数索引值是-1(最后一个元素),-2(倒数第二个元素。

 实际上,几乎没有人使用除了-1 之外的其它的负数索引值。

 eg. $rocks[$#rocks] = ‘hard rock’; #the last rock

  $rocks[-1] = ‘hard rock’; #完成上例中的一种更简单的方法

  

15. 列表:

 (1 ..100) #包含100 个整数的列表

 (5 ..1) #空列表— ..中的左值应小于右值,否则为空

 (1.7..5.7) #同上— 最小值和最大值被转换成整数

 

16. qw缩写

 (“fred”, “barney”, “betty”, “wilma”, “dino”)

 qw(fred barney betty wilma dino ) #同上,但输入更少

  qw 表示“quoted words”或者“quoted by whitespace,”这依赖于你问的是谁。无论那种解释,Perl 将它们当作单引号字符串

 处理,你不能像双引号那样在qw 中使用\n 和$fred。whitespace(空格,像spaces,tabs,newlines 等字符串)将被忽略,剩下

 的组成了列表的元素。

  由于qw 是一种引用,因此不可以在qw 内添加注释。

 Perl 允许使用任何标点符号作为分界符

  qw ! fred barney betty wilma dino !

  qw# fred barney betty wilma dino # #有些像注释

  qw( fred barney betty wilma dino )

  qw{ fred barney betty wilma dino }

  qw[ fred barney betty wilma dino ]

  qw< fred barney betty wilma dino >

 如果不想或者不能改变分界符,那可以使用反斜线(\):

 qw!Yahoo\! Google excite lycos ! #其中一个元素为:字符串yahoo!

 

17. 列表赋值

 ($fred, $barney, $dino) = (“flintstone”, “rubble”, undef);

 ($fred, $barney) = ($barney, $fred) #交换两个变量

 

18. 在数组名前加@(后没有中括号)来引用整个数组

 @rocks = qw / bedrock slate lava /;

 @copy = @quarry; #将一个数组中的值拷贝的另一个数组中

 

19. 数组不能成为列表的一个元素的原因是数组只能包含标量值,不能包含其它的数组

 没有赋值的数组变量的值为( ),空表。

 

20. shift 和unshift 操作

 push 和pop 对数组的末尾进行操作。相应的,unshift 和shift 对一个数组的开头进行操作

 @array = qw# dino fred barney #;

 $m = shift (@array); #$m 得到“dino”, @array 现在为(“fred”, “barney”)

 

 unshift(@array,5); #@array 现在为(5)

 unshift @array,4; #@array 现在为(4,5)

 

21. foreach 控制结构

 foreach $rocks(@rocks){}

 控制变量(本例中为$rock)每一次迭代从列表中取出一个新值.控制变量不是这些列表元素中的一个拷贝而是这些元素本身。

也就是说,如果在循环中修改这个变量,那原始列表中的元素也会被修改.

 如果在foreach 循环中省略了控制变量,那Perl 会使用其默认的变量:$_

 

22. reverse操作(Perl 通常先计算变量的值(赋值号右边),再进行赋值)

 @fred = 6 ..10;

 @barney = reverse (@fred); #得到10,9,8,7,6

 @wilma = reverse 6 ..10; #同上,没有使用额外的数组

 @fred = reverse @fred; #将逆转过的字符串存回去

 注意reverse 返回逆转的列表,它不会改变其参数的值。如果返回值没有赋值给某个变量,那这个操作是没有什么意义的

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

 

23. 强制转换为标量Context(函数scalar)

 @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”; #正确,输出其数字

 

24. <STDIN>在标量context 中返回输入的下一行。在列表context 中,它将返回这个输入文件的所有剩余部分。而每一行将作为一个独立的元素

 

25. 定义子程序

 要定义自己的子程序,使用关键字sub,子程序的名字(无&这个符号)

 sub marine {

 $n + = 1; #全局变量$n

 print “Hello, sailor number $n!\n”;

 }

 ◆子程序的定义是全局的

 ◆Perl 中没有私有子程序

 ◆如果两个子程序有相同的名字,那后一个将覆盖前一个

 ◆所有的Perl 子程序都会返回值,在Perl 中返回值和不返回值是没有区别的

 

26. 当Perl 遍历此子程序时,将会计算每一步的值。子程序中最后计算的表达式的值将被返回。

 sub sum{

 $fred + $barney; #返回值

 }

 $fred = 3;

 $barney = 4;

 $wilma = $sum_of_fred_and_barney; #$wilma 得到7

 最后一个被计算的表达式是print 语句时,其返回值通常为1,意思是“print was succfessful(打印成功)”

 

27. @_是子程序的一个私有变量;如果有一个全局变量@_,它将在此子程序调用前存储起来,当子程序调用完成后,

 其早期的值会被重新赋还给@_

 ◆除非调用的子程序前有&而后面没有括号(或者没有参数),此时@_从此调用者的上下文(context)得到

 

28. 可以任意时候使用my创建私有变量:

 sub max {

 my($m,$n); #新的,私有变量

 ($m,$n) = @_; #赋值

 if($m > $n) {$m} else{$n}

 }

 

29. 在if 代码块内部,其语句没有分号。Perl 允许省略括号中最后一条语句的分号,在实际代码中,通常仅当此代码

块仅包含一条语句时才省略此分号。

 

30. 如果没有使用括号,my 仅定义一个变量

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

 my $num = @_; #标量context,同$num = @_;

 

31. 如果新的变量没被赋值的话:标量变量会自动赋与undef,而数组变量会赋与空列表。

 

32. 告诉Perl 进行更严格的语法检测,需要在程序顶端use strict(或者在任意块或者文件中,如果你需要在此部分使用它):

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

 现在,除了其它限制外,Perl 将要求你在申明每一个新的变量时,使用my.

 

33. 省略符号&的规则:

 (1)如果用括号将一些参数括起来,那其为函数调用

 (2)如果Perl 内部的编译器知道此子程序的定义,则可以省掉其参数的括号:

  sub division{

  $_[0] / $_[1]; #第一个参数除以第二个参数

  }

  my $quotient = division 355, 113; #可以省略掉括号

  不要将上述子程序的声明放在调用函数的后面,否则编译器不知道调用division 是什么意思。

 (3)如果子程序和Perl 一个内嵌程序同名,则必须使用&来调用它

 

34. $ ./my_program fred barney betty

上述命令的含义是,运行my_program(在当前目录下),它将处理文件fred,再处理文件barney,最后是文件betty

如果没有命令行参数,程序将处理标准输入流(standard input stream)。作为一个特例,如果将连接号(-)作为一个参数,其

含义也是标准输入◆。如果调用参数为fred –betty,其含义是程序将首先处理文件fred,其次是标准输入流,最后是文件betty。

 

35. 由于<>通常被用来处理所有的输入,因此在同一个序中重复使用是不正确的。如果在同一个程序中使用了2 次<>,特别是

在while 循环内第二次使用<>读入第一次<>的值,其结果通常不是你所希望的

 perl中<>运算符可以有如下的用途:

 1)如果尖括号中间是文件句柄,尖括号运算符允许你读取文件句柄,比如<STDIN>。

 2) 如果尖括号中间是搜索模式,尖括号运算符能返回与该模式匹配的文件列表,这称为一个glob,比如< *.bat>。

 3)一组尖括号运算符如果中间没有任何东西,那么它可以读取命令行上所有文件的内容;如果没有给出文件名,则可以读取标准输出。

 

36. 在函数调用中,函数名字后面会紧接着括号,其中为函数的参数

 当print 后面是一个开括号时,print 为函数调用,它将输出括号中的内容

 print (2+3);

 上述代码看起来像函数调用,它实际上就是函数调用。其输出为5,然后返回一个值

 $result = print(“hello world\n”); #返回的值通常为1

 

37. 使用printf 格式化输出

 (1)printf 中的数据通常会接受一个宽度值。如果数据不能满足这个宽度,则会自动扩展开来

 printf “%6f\n”, 42; #输出为○○○○42(○此处指代空格)

 (2)%s 是针对字符串的,例如:printf “%10s\n”, “wilma”; #输出为:○○○○○wilma

 (3)如果宽度值为负数,则为左对齐(对于所有的格式符):print “%-15s\n”, “flintstone”; #输出为flintstone○○○○

 (4)%f 根据需要进行截尾,你可以设置需要几位小数点后面的数字:

 printf “%12f\n”, 6*7 + 2/3; #输出为: ○○○42.666667

 printf “%12.3f\n”, 6*7 + 2/3; #输出为: ○○○○○○42.667

 printf “%12.0f\n”, 6*7 + 2/3; #输出为: ○○○○○○○○○○43

 (5)要输出一个百分号,可以使用%%,它不会使用后面列表中的元素

 print “Monthly interest rate: %.2f%%\n”,

 5.25/12; #输出的值为0.44%

 格式化输出中,在百分号前使用反斜线(\),这是不正确的(格式是表达式,“\%”是指一个字符的字符串‘%’。)

 

38. Perl 自身有六个文件句柄:STDIN,STDOUT,STDERR,DATA,ARGV,ARGVOUT (Larry 推荐文件句柄的所有字母均大写)

 

39. grep命令可以去掉任何没有特别指定的信息

 

40. 使用echo指令向文件写入内容

 (1)使用>指令覆盖文件原内容并重新输入内容,若文件不存在则创建文件。(eg. echo "Raspberry" > test.txt)

 (2)使用>>指令向文件追加内容,原内容将保存。

 

41. 文件句柄的打开

open CONFIG, “dino”; #打开了一个名为CONFIG 的文件句柄,它指向dino 文件。文件dino 所包含的数据通过CONFIG 传给程序。

open CONFIG, “<dino”; #它和第一例是一样的,只是< 明确的指明了“使用这个文件进行输入操作”,虽然默认的情况就是输入(没有<)

open BEDROCK, “>fred”; #打开文件句柄BEDROCK,输出到新文件fred 中。和shell 重定位中使用的大于号一样,我们将输出送到文件fred 中。

      如果存在这样的文件,则清空它..

 

42. 当结束一个文件句柄时,你可以如下这样关闭它:close BEDROCK;

 如果程序重新打开它(也就是说,使用open 重新打开此文件句柄),或者退出程序◆,Perl 将自动关闭文件句柄。

 

43. die 函数创建我们自己的严重错误(die 函数将打印出你给它的消息(利用标准错误流),并确保程序退出时为非零(nonzero)的退出状态)

 if(!open LOG, “>>logfile”){

 die “Cannot create logfile:$!”;

 }

如果open 失败,则die 将结束程序,并告诉你不能创建logfile。消息中的$!是系统产生的一些可读的信息

die 还会自动将Perl 程序的名字和行数输出在消息的末尾,因此能轻易的辨别出是哪一个die 引起的错误

eg. Cannot create logfile: permission denied at your_program line 1234.

如果不想要函数和文件的名字,只需在die 消息后面加上换行符

◆作为一般规则,如果用法错误则在消息后面加上换行符;如果是其它错误,需要利用它来调试,则不要加上换行符

◆程序的名字在Perl 的特殊变量$0 中,因此你可能将它包含在: “$0:Not enough arguments\n”。这对于在管道中的程序或者shell 脚本是非

常有用的。因为:$0 在程序运行时不断的变化。你可以查看_ _FILE_ _和_ _LINE_ _(或者caller 函数)来了解被加上换行符后忽略的

信息,从而可以按你自己的格式输出它们。

 

44. 改变默认的输出句柄

默认情况下,如果不指定文件句柄给print(或者printf,这里的内容对两者均适用),则默认会使用STDOUT。但这个默认属

性,可以通过select 操作进行更改。如下:

select BEDROCK;

print “I hope Mr. Slate doesn’t find out about this.\n”;

print “Wilma!\n”

◆默认情况,输出到文件句柄的内容会被缓存起来。将变量$|设置为1,将会在输出操作结束时会立刻清空文件句柄.

 

45. 要访问hash 元素,可以使用下面的语法:$hash{$some_key}

 

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

 为了方便,hash 可以转换为列表,或者反过来。给hash 赋值,其类型属于列表context 赋值,其中列表是key/value 对:

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

 hash 的值(在列表context 中)是一个key/value 对的列表:@array_array = %some_hash;

 

47. keys 函数会返回此hash 的所有keys,values 函数将返回所有的values。如果hash 中没有元素,则此函数将返回空列表:

 my %hash = (“a”=>1, “b”=>2, “c”=>3);

 my @k = keys %hash;

 my@v = values %hash;

 ◆keys按照某种顺序存储,则其对应的values 也是这个顺序

 

48. each函数:

 如果想迭代hash 的每一个元素(如,检查每一个元素),一种通常的方法是使用each 函数,它将返回key/value 对的2元素列表

 while (($key, $value) = each %hash){

 print “$key => $value\n”;

 }

 

49. exists函数:要查看hash 中是否存在某个key,可以使用exists 函数,如果hash 中存在此key,则返回true,这和是否有对应的value 无关

 if(exists $books{$dino}){

 print “Hey, there’s a libaray card for dino!\n”;

 }

 

50. 要匹配某个模式(正则表达式)和$_的关系,可以将模式放在正斜线(//)之间,如下:

 $_ =“yabba dabba doo”;

 if(/abba/){

 print “It matched!\n”;

 }

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

 

51. 元字符

 (1)点(.)是通配符,它可以匹配任何单个的字符,但不包括换行符(“\n”)。因此,模式/bet.y/将匹配betty。同时也匹配betsy,

 bet=y, bet.y,或者说任意字符串后接bet,然后是任意的单个字符(不包括换行符),后接y。它不会匹配bety,betsey,因为

 t 和y 之间不是一个字符。点(.)只匹配一个字符。

 (2)元字符前使用反斜线将使它变成普通的字符:模式/3\.14159/中的点(.)即不是通配符

 (3).*叫做“任意字符串匹配模式”,因为任意的字符串均能被匹配上(不包括换行符)。

 /fred.*barney/将匹配fred,和barney 之间有任意多个任意字符(不含换行符)的字符串。任意行如果前面有fred,后面有barney,其间为任

 意字符(字符串)都将匹配上

 (4)选择符:竖线(|),在这种用法中通常被读作“或(or)”,意思是匹配左边的或者右边的。如果竖线左边没有匹配上,则匹配右边。因

 此,/fred|barney|betty/将匹配出现过fred,或者barney,或者betty 的字符串 

 

52. 字符类,是方括号[]中的一列字符,可以匹配上括号内出现的任意单个字符。它匹配一个字符,但这个字符可以是列中的任意一个

 eg. 字符类[abcwxyz]可以匹配上括号内七个字母中的任意一个

 字符类前使用符号^将取此字符类的补集。也就是说,[^def]]将匹配上这三个字符中之外的任意单个字符

 (1)任何数字的类,[0-9],可以被简写为:\d

 (2)\w 被称作“word’字符:[A-Za-z0-9_]。(字母,数字,下划线组成)\w 不能匹配单词,而只能匹配单个字符

 (3)\s 对于匹配空白(whitespace)将非常方便。它等价于[\f\t\n\r ]

 (4)/s匹配任意字符包括换行符(同字符类[\d\D]的行为类似)

 $_ = “I saw Barney\ndown at the bowing alley\nwith Fred\nlast night.\n”;

 if(/Barney.*Fred/s){

 print “That string mentions Fred after Barney!\n”;

 }

 如果不使用/s,那么上述模式将不能被匹配上,因为这两个字符不在同一行中。

 (5)/x 修饰符,允许你在模式中加入任何数量的空白,以方便阅读:

  /-?\d+\.?\d*/ #这是什么含义?

  / -? \d+ \.? \d* /x #要好些

 Perl 中,注释可以被作为空白,因此使用/x,可以在模式中加上注释:

  /

  -? #可选的负号

  \d+ #小数点前一个或多个十进制数字

  \.? #可选的小数点

  \d* #小数点后一些可选的十进制数字

  /x #模式结束

 井号(#)表示后面是注释,如果需要匹配井号,可以使用\#或[#]

 

53. 锚定

 ◆符号^(脱字字符)表示在字符串的开头进行匹配,而符号$则表示在结尾(/^fred$/能同时匹配上“fred”和“fred\n”)

 ◆词界锚定,\b,是针对单词使用的。如/\bfred\b/可以匹配上单词fred,但不能匹配frederick(非词界锚定为\B)

 

54. 绑定操作符,=~:告诉Perl 将右边的模式在左边的字符串上进行匹配,而非对$_匹配

 

55. 匹配变量

 使用括号是由于它可以将模式的某一部分组合起来。同时括号也会引起正则表达式分配新的内存块。这些内存含有括号中

 的模式所匹配的字符串。如果有不止一对括号,那就不止一块内存块。每一个内存块内有一段字符串,而非模式的一部分.

 在Perl 中,它们具有像$1, $2 这样的名字。变量个数同模式中括号对数的个数是相同的。

 

56. 自动匹配变量:$&为整个被匹配的部分,匹配部分的前一部分存放在$`之中,后一部分被存到$'

 

57. 优先级

(1)在此优先级表的最顶端是括号:(()),在分组和引用内存值的时候使用

(2)第二级是数量词。这里有星号(*), 加号(+),问号(?)以及由花括号表示的数量词

(3)第三级的是锚定和序列

(4)优先级最低的是竖线(|),表示或

 

58. 使用s///进行替换(只进行一次替换),它将替换变量中模式所匹配上的部分.如果没有匹配上,则什么也不会发生,此变量也不会有任何更改

◆同m//不一样,m//可以和任何字符串表达式进行匹配,s///只能修改被称为左值(lvalue)的数据。

◆使用/g 进行全局替换

 

59. 大小写转换

\U 要求紧接着的均是大写;

 $_ =“I saw Barney with Fred.”;

 s/(fred|barney)/\U$1/gi; #$_现在是“I saw BARNEY with FRED.”

\L要求后面的均为小写;

默认时,会影响到剩余的(替换的)字符串。可以使用\E 来改变这种影响

使用小写形式时(\l 和\u),只作用于下一个字符

 

60. split操作:@fields = split /separtor/, $string;

 

61. join 函数类似于:my $result = join $glue, @pieces;

join 函数的第一个参数是粘合元素(glue),它可以是任意字符串。剩下的参数是要被粘合的部分。join 将粘合元素添加在这

些部分之间,并返回其结果:my $x = join“:”, 4, 6, 8, 10, 12; #$x 为“4:6:8:10:12”

my $y = join “foo”, “bar”; #得到“bar”

 

61. 匹配多行文本

 锚定^和$是指整个字符串的开头和结束。但/m 这个正则表达式选项允许它们根据内部的换行符进行匹配(将

 m看作多行(think m for multiple lines))。这时锚定针对每一行,而非整个字符串

 eg.$_ =“I’am much better\nthan Barney is\nat bowling,\nWilma,\n”;

  /^wilma\b/im

  

62. 非捕捉用的括号

 括号可以捕捉匹配上的字符串,并将它们存入变量之中,如果只想用括号将某部分进行分组,在开括号后面加上一个问号和冒号,(?:)

 if(/(?:bronto)?saurus (steak|burger)/)

 {

 print “Fred wants a $1\n”;

 }

  

63. 控制语句

 (1)在条件为假时执行,可以使用unless(同if的情况相反)

 (2)将while 循环的条件部分取反。此时,可以使用until

 

64. 循环控制:

 (1)last 会立刻结束循环。(这同C 语言或其它语言中的“break”语句类似)

 (2)next 之后,又会进入下一轮循环(这和C 或者类似语言的“continue”相似)

 (3)redo会调到当前循环块的顶端,不进行条件表达式判断以及接着本次循环

  my @words = qw{ fred barney pebbles dinoWilma betty };

  my $errors = 0;

  foreach(@words){

  ##redo 跳到这里##

  print “Type the word ‘$_’: ”;

  chomp(my $try = <STDIN>);

  if($try ne $_){

  print “sorry –That’s not right.\n\n”;

  $errors++;

  redo; #跳转到循环顶端

  }

  }

  

65. 短路操作的值

 和C(以及类似的语言)不同的地方是,短路操作的结果是最后被执行语句的返回值,而非仅仅是一个Boolean 值。结果

 是相同的。如果最后被执行的部分为真,则整个为真;为假,则整个为假

 eg. my $last_name = $last_name{$someone} ||‘(No last name)’

  

66. oct 函数,它会强迫将某个字符串按照八进制来解释,无论其前面是否有0:

 0775八进制数,被当成字符串是会得到十进制数755.($p = "0775" #十进制数755)

 

67. 你可以使用chown 函数改变一批文件的所有者及所在的组。所有者及组是同时改变的

◆调用getpwnam 函数,将名字转换为数字,而对应的getgrnam将组名转换为数字

eg. defined(my $user = getpwnam “merlyn”) or die “bad user”;

 defined(my $group = getprnam “users”) or die “bad group”;

 chown $user, $group, glob “/home/Merlyn/*”;

 

68. 改变时间戳(更新当前目录下的所有文件,使它们看起来是昨天修改的,而访问时间为现在)

 my $now = time;

 my $ago = $now -24*60*60; #一天的秒数

 utime $now, $ago, glob “*”; #设成当前访问的,一天之前修改的

 第三个时间戳(ctime 的值)永远是“now”

 

69. Perl 查找子串第一次在大字符串中出现的地方,返回第一个字符的位置。字符位置是从0 开始编号的

 $where = index($big, $small);

 第三个参数告诉程序从后面的某个地方开始查询。返回-1表示没有找到

 

64. 想知道某个子串最后出现的位置,可以使用rindex 函数来做到

 rindex 函数也有可选的第三个参数;此时,它给出的是可能的最大值:

 my $fred = “Yabba dabba doo!”;

 my $where1 = rindex($fred, “abba”); #$where1 得到7

 my $where2 = rindex($fred, “abba”, $where - 1); #$where2 得到1

 my $where3 =rindex($fred, “abba”, $where2-1); #$whrere3 得到-1

 

65. my $mineral = substr(“Fred J. Flintstone”, 8, 5); #得到“Flint”

 my $rock = substr“Fred J. Flintstone”, 13, 1000; #得到“stone

 my $pebble = substr “Fred J. Flintsone”, 13; #得到“stone”

 初始位置可以是负的,表示从字符串结尾处开始

 my $out = substr (“some very long string”, -3, 2); # $out 得到“in”

 

66. ◆字符串中选择的相应位置是可以改变的

 my $string = “Hello, world!”;

 substr($string, 0, 5) = “Goodbye”; # $string 现在变成了“Goodbye, world!”

 ◆可以使用绑定操作符(=~)来将此运算限制在字符串的某一个部分

 substr($string, -20) =~ s/fred/barney/g;(在我们自己的代码中,从没有用到过上述功能)

 ◆用susbtr:使用4 个参数,第四个参数是替换的字符串:

 my $previous_value = substr($string, 0, 5, “Goodbye”);

 

67. 在Linux环境中创建函数并写入内容

 $cat >show-args

 foreach $args (@ARGV){

 print “one arg is $arg\n”;

 }

 ^D

 $ perl show-args *.pm

68. system函数创建子进程,它会立刻去执行请求的操作,Perl 则暂停。exec 函数引起Perl 

自己处理请求的操作。可以将它看作“goto”而非子程序调用 

 

69. 使用反引号捕捉输出

 system 'date';

 my $now = `date`; #捕获date 的输出

 print “The time is now $now”; #已经有换行符

 

70. 打开管道:开始一个并发(并行)子进程的语法是将命令作为“文件名”传给open,并在其前面或后面加上竖线(|),

竖线是“管道(pipe)”符

要从文件句柄中读入数据,我们可以使用通常的方法:my $now = <DATE>;

要将数据送给mail 进程,一个简单的打印文件句柄就可以了:print MAIL“The time is now $now”

 

71. fork: 一个进程,包括代码、数据和分配给进程的资源。

 fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,

 但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。

    一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。

 然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。

 相当于克隆了一个自己。

 

72. 利用eval 捕获错误(eval块是一个表达式)

当执行eval 块时发生了通常的严重错误,eval 块会停止执行,但程序不会崩溃。当eval 结束时,你想知道它是正常结束的,

还是发生了严重错误。这些结果放在特殊变量$@之中。如果eval 为你捕捉了严重错误,则$@中将有程序失败的原因,可

能如:Illegal division by zero at my_program line 12。如果没有错误,则$@为空.

◆如果没有错误,就像任何的子程序一样:返回值为最后一个被求值的表达式的值,或者是由return 返回的值。

my $barney = eval { $fred / $dino };

 

73. (1)使用grep 在列表得到元素

 my @odd_number = grep{$_%2}1..100;#得到1到100之间所有的奇数

 (2)使用map 对列表项进行变换

 my @data = (4.75, 1.5, 2, 1234, 6.9456, 12345678.9, 29.95);

 my @formatted_data = map {&big_money($_)} @data;

 

74. Slices:从列表中取出部分内容(array与hash有类似的用法)

 eg. my($card_num, $count) = (split /:/)[1,5];

 对于%score:

 my @three_score = ($score{“barney”}, $score{“fred”}, $score{“dino”}); or

 my @three_scores = @score{ qw/ barney fred dino/ };

 

75. eg. &printletter("hello world");

 #按照指定格式输出

 sub printletter{

 my $words = shift;

 print <<EOF;

 $words

 yours faithfully,

 

 EOF

 }

 #输出结果:

 hello world

 yours faithfully,

 

 ############

 

76. 使用bless进行引用邦定

my $a={};

print "\$a is a ", ref $a, " reference!\n"; # $a is a HASH reference!

bless($a, "Person");

print "\$a is a ", ref $a, " reference!\n"; # $a is a Person reference!

 

77. sub surname{

 my $self = shift;

 #区分对象方法和类方法的调用,表明这是一个对象方法, 不是类方法

 #Person->surname "error"

 #$peron->surname

 unless(ref $self){

  print "Error! This is a class method call!\n";

 }

 my $data = shift;

 $self->{surname}=$data if defined $data;

 return $self->{surname};

 简写:

 sub surname{$_[0]->{surname} = $_[1] if defined $_[1];$_[0]->{surname}}

}

 

78. 继承(通过@ISA只能继承方法,不能继承数据。)

our @ISA = qw(Person);

 

79. isa($package) will return true if your class inherits from that package.

 can($method) is true if your class can perform the named method.

 VERSION returns the value of the package variable $VERSION in your class, if one exists.

 

80. To tie a variable to a class:

 tie $var, 'Class', @parameters;

 

 For a scalar

 TIESCALAR(@parameters)

 FETCH()

 STORE($value)

 

 For a array

 TIESCALAR(@parameters)

 FETCH($element)

 STORE($element,$value)

 FETCHSIZE()

 STORESIZE($size)

 

 (1)package Autoincrement;

 #在相应的package('Class')要有对应的TIESCALAR, TIEHASH, TIEARRAY, TIEHANDLE等

 #perl expects to call TIESCALAR

 sub TIESCALAR{

  my $class = shift;

  my $realdata= 0;

  return bless\$realdata,$class;

  } 

  1;

 (2)取对应的值

 sub FETCH{

  my $self = shift;

  return $$self++;

 }

 (3)改变对应的值

 sub STORE{

  my $self = shift;

  my $value = shift;

  $$self = 0;

 }

 

81. (1)Use CamelCase for class and local variable names

 (2)All private method names must start with an underscore.

 (3)Use CamelCase for all public methods

 (4)Use CamelCase for all object definitions

 

82. map函数

 使用一个列表,对每个元素以一个指定的代码块或表达式进行求值运算,然后返回所有结果的一个列表。

 在代码块中,map使用局部的符号$_当作当前列表元素的别称。

 my @phase = qw(korn jerry);

 my @words = map{/(^\S)/} @phase;

 print "@words\n";

 ##########

 k j

 

83. use Cwd;

 getcwd();#获取当前路径

 

84. Linux下删除目录命令"rm":

  -i 删除前逐一询问确认

  -f 强制删除

  -r 将目录及以下之档案文件一并删除

  

  

文件比较运算符

-e filename 如果 filename存在,则为真 [ -e /var/log/syslog ]

-d filename 如果 filename为目录,则为真 [ -d /tmp/mydir ]

-f filename 如果 filename为常规文件,则为真 [ -f /usr/bin/grep ]

-L filename 如果 filename为符号链接,则为真 [ -L /usr/bin/grep ]

-r filename 如果 filename可读,则为真 [ -r /var/log/syslog ]

-w filename 如果 filename可写,则为真 [ -w /var/mytmp.txt ]

-x filename 如果 filename可执行,则为真 [ -L /usr/bin/grep ]

filename1-nt filename2 如果 filename1比 filename2新,则为真 [ /tmp/install/etc/services -nt /etc/services ]

filename1-ot filename2 如果 filename1比 filename2旧,则为真 [ /boot/bzImage -ot arch/i386/boot/bzImage ]

 

sed命令

*、+限定符都是贪婪的,因为它们会尽可能多的匹配文字,只有在它们的后面加上一个?就可以实现非贪婪或最小匹配

 

2>&1(把标准错误重定向到标准输出)

几个基本符号及其含义

0 表示stdin标准输入

1 表示stdout标准输出

2 表示stderr标准错误

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值