加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Perl 入门

发布时间:2020-12-16 00:14:52 所属栏目:大数据 来源:网络整理
导读:1. Perl 也允许使用非10 为底的数字。八进制以0 开头,十六进制以0x 开头,二进制0b 开头.在十 六进制中A 到F(或者a 到f)分别表示10 到15: 0377 #八进制数字377,等同于十进制数字255 0xff #十六进制数字FF,等同于十进制数字255 0b22222111 #等同于十进
1. Perl 也允许使用非10 为底的数字。八进制以0 开头,十六进制以0x 开头,二进制0b 开头.在十 六进制中A 到F(或者a 到f)分别表示10 到15: 0377 #八进制数字377,等同于十进制数字255 0xff #十六进制数字FF,等同于十进制数字255 0b22222111 #等同于十进制数字255 2. Perl 除了提供通常的操作符加(+),减(-),乘(*),除(/)等等之外: 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… … 还提供了模数运算符(%)。10%3 的值是10 除以3 的余数 如2**3,表示2 的3 次方,等于 3. 字符串是一串字符(如hello)。字符串可能是字符的任意组合◆。最短的字符串不含任何字符。最长的字符串,可以填满整个内存. ◆和C,C++不同,Perl 中NUL 字符没有特殊的含义。Perl 能计算长度,不用靠null 来判断字符串是否结束。 和数字一样,字符串也可由文字符号(literal)来表示,它用来在Perl 程序中代表某个字符串。有两种类型的字符串:单引号字符串和双引号字符串。 除了单引号,或者反斜线(包括换行字符,如果字符串在下一行继续)之外的任何字符都表示它自身 ‘fred’ #四个字符:f,r,e,d ‘barney’#六个字符 ‘’ #空字符(没有字符) ‘Don’t let an apostrophe end this string prematruely!’ ‘the last character of this string is a backslash: ’ ‘hellon’#hello 紧跟着反斜线和n ‘hello there’ #hello,换行,there (共11 个字符) ‘’’ #单引号(’)跟着反斜线() 双引号字符串和在其它语言类似。它也是字符的序列,不同点在于,其由双引号括起来的。现在,反斜线可以用来表示控制字符,或者八进制,十六进制数的表示。下面是一些双引号字符串的例子: “barney”#等同于‘barney’ “hello worldn”#hello world,换行 “the last character of this string is a quote mark:”” “coketsprite”# coke,a tab(一个制表符),sprite “hello”. “world” # 同于“helloworld” “hello”. ‘’. “world”#同于“hello world” ‘hello world’. “n” #同于“hello worldn” “fred”x 3 # “fredfredfred” “barney”x (4+1) # “barney”x 5,“barneybarneybarneybarneybarney” 5 x 4 #实际上是“5”x 4,“5555” 4. 数字和字符串之间的自动转换 当在需要数字的地方使用了字符串(如,乘法),Perl 将自动把字符串转换为其等价的数字,就像输入的是十进制浮点数一 样◆。因此“12”* “3”将给出36。后面的非数字部分和前面的空格将被去掉,如“12fred34”* “3”将给出36 而不会用任何 提示◆。在极端情形,当一个不含任何数字的字符串将别转换为0。如,将“fred”当作数字来使用时。 5. 标量变量可以存放一个标量值。 标量变量的名字由一个美圆符号($)后接Perl 标识符:由字母或下划线开头,后接字母,数字,或者下划线。或者说由字母,数字和下划线组成,但不能由数字开头。大小写是严格区分的:变量$Fred 和变量$fred 是不同的。任意字母,数字,下划线都有意义,如: $a_very_long_variable_that_ends_in_1 标量赋值 $fred = 17; #将17 赋给变量$fred $barney =‘hello’; #将五个字母的字符串‘hello’赋给$barney $barney = $fred + 3;# 将$fred 的值加上三赋给$barney (20) $barney= $barney*2;#将变量$barney 乘2 再赋给$barney (40) $barney = $barney*3;?? ?$barney*=3; $str = str . “”; #$str 后接空格 $str .= “”’; #同上 6. 字符串中标量变量的内插 $mean = “brontosaurus steak”; $barney = “fred ate a $meal”; #$barney 现在是“fred ate a brontosaurus steak” $barney = ‘fred ate a’. $meal; #同上 如果一个变量未被赋值,则将使用空值替换 print “$fred”; #引号是没有必要的 print $fred; #更好的写法 在字符串中变量前($符号前)加上反斜线(),变量将不会被内插(替换): $fred = ‘hello’; print “The name is $fred .n”; #打印出美圆符号,变量不会被其值替换 print ‘The name is $fred’. “n”; #同上 print "Try to get value of $fred: $fredn"; 变量名将是字符串中有意义的最长的那一个。这可能在当你需要在某次匹配就替换的情况下出问题。Perl 提供了一种类似于shell 的分隔符:花括号({})。用花括号将变量名括起来。或者将字符串分隔成几个部分,再用连接符( . )串起来: $fred = "Kelvin"; $freds = "Damon"; print "Try to get value of n$fred: ${fred}sn$freds: $fredsn${freds}n"; 7. 比较运算符 35 != 30+5 #false 35 == 35.0 #true ‘35’eq‘35.0’ #false (按照字符串比较) ‘fred’lt ‘barney’ #false ‘fred’lt ‘free’ #true ‘fred’eq ‘fred’ #true ‘fred’eq ‘Fred’ #false ‘’gt ‘’ #true 8. 控制结构 if if($name gt ‘fred’){ print “‘$name’comes after ‘fred’in sorted order.n”; }else{ print “‘$name’does not come after ‘fred’.n”; print “Maybe it’s the same string,in fact.n”; } while $count = 0; while ($count < 10) { $count + = 2; print “count is now $countn”; #打印出2 4 6 8 10 } foreach @rocks = qw/ bedrock slate lava /; foreach $rocks(@rocks){ $rock = “t$rock”; #@rocks 的每一个元素前加入一个tab $rock . = “n”; #每一个元素后加一个换行符 } print “The rocks are:n”,@rocks; #每一个元素都被缩进了,并且一个元素占一行 类似Boolean类型 $is_bigger = $name gt‘fred’; if($is_bigger){… } 判断依据 ● 如果值为数字,0 是false;其余为真 ● 如果值为字符串,则空串(‘’)为false;其余为真 ● 如果值的类型既不是数字又不是字符串,则将其转换为数字或字符串后再利用上述规则◆。 这意味着undef(很快会看到)为false。所有的引用(在Alpaca 书中有详细讨论)都是true。 字符串‘0’是唯一一个非空但值为0 的串。 9. 用户输入 $line = <STDIN>; if($line eq “n”){ print “That was just a blank line!n”; }else{ print “That line of input was: $line”; } 完全正确,只是有未初始化的警告: #n = 1; while($n < 3){ $sum += $n; $n +=1; } print "The total was $sum.n"; 10. 常用函数 define:检查是否初始化 $madonna = <STDIN>; If ($defined ($madonna)){ print “The input was $madonna”; }else{ print “No input available!n”; } qw: 实践表明,字符串的列表(如上例)在Perl 中经常使用。有一种简便的方法可以不用输入大量的引号而达到类似的功能,那就是使用qw。qw 表示“quoted words”或者“quoted by whitespace” (“fred”,“barney”,“betty”,“wilma”,“dino”) qw(fred barney betty wilma dino ) #同上,但输入更少 chomp:去掉最后的n $line = "abncn"; print $line; chomp($line); print $line; chomp (@lines = <STDIN>); #读入所有的行,不包括换行符 reverse reverse(逆转)操作将输入的一串列表(可能是数组)按相反的顺序返回。如果不喜欢范围操作符: .,只能从小到大,那可以使用 reverse 来解决这个问题: @fred = 6 . .10; @barney = reverse (@fred); @wilma = reverse 6 . .10; @fred = reverse @fred; #得到 10,9,8,7,6 #同上,没有使用额外的数组 sort:需要将结果存回原数据结构 sort 操作将输入的一串列表(可能是数组)根据内部的字符顺序进行排序。如对于 ASCII 字符串,将根据 ASCII 序进行排 序。当然,ASCII 中有一些奇怪的地方,如大写字母在小写字符的前面,数字在字符的前面,而标点符号散布在各处。但按 ASCII 排序只是其默认的行为,在第十三章中,可以看到如何按你想要的顺序进行排序的方法: @rocks = qw/ bedrock slate rubble granite /; #得到 bedrock,granite,rubble,slate @sorted = sort(@rocks); @back = reverse sort @rocks; #为 slate 到 bedrock @rocks = sort @rocks; @numbers = sort 97 . .102; #将排序的值写回@rocks #得到 100,101,102,97,98,99 scalar:告诉 Perl 提供一个标量 context 偶尔,你可能需要标量 context 而 Perl 期望的是列表。这种情况下,可以使用函数 scalar。它不是一个真实的函数因为其仅 是告诉 Perl 提供一个标量 context: @rocks = qw(talc quartz jade obsidian); print “ How many rocks do you have?n” ; print “ have ” @rocks,“ I,rocks!n” ; print “ have ” scalar @rocks,rocks!n” ; #错误,输出 rocks 的名字 #正确,输出其数字 reverse: hash 的反转,键值调换,如有重复键,最后一次的值保留: %inverse_hash = reverse %any_hash; keys 函数会返回此 hash 的所有 keys,values 函数将返回所有的 values。如果 hash 中没有元素,则此函数将返回空列表: my %hash = (“ a”=>1,“ b”=>2,“ c”=>3); my @k = keys %hash; my @v = values %hash; 11. 数组和列表 $arr[0] = "2"; $arr[5] = "4"; print $arr[0]*$arr[$#arr]."n";? #8 print $arr[0]*$arr[$#arr+1]."n"; #0 print $arr[0]*$arr[-1]."n";? #8. if use -2,it represents nodes before the last one @rocks = qw(aa bb cc dd); $num = $#rocks; print "$rocks[$num]n"; 数组是由括号括起来并且其元素由逗号分隔开的列表。这些值组成了数组的元素: (1 ..5) #同(1,2,3,4,5) (1.7..5.7) #同上— 最小值和最大值被转换成整数 (5 ..1) #空列表— ..中的左值应小于右值,否则为空 (0,2 .. 6,10,12)#同(0,2,3,4,5,6,10,12) ($m ..$n) #由$m 和$n 的值决定 (0 .. $#rocks) #上节中有$#rocks 的介绍 列表赋值 ($fred,$barney,$dino) = (“flintstone”,“rubble”,undef); ($fred,$barney) = ($barney,$fred) #交换两个变量 ($betty[0],$betty[1]) = ($betty[1],$betty[0]); ($fred,$barney) = qw <flintstone rubble slate granite>; #两个值被忽略了 ($wilma,$dino) = qw[flintstone]; #$dino 为undef @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); @copy = @quarry; #将一个数组中的值拷贝的另一个数组中 pop @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 被丢弃了) 如果数组为空,那pop 什么也不做(因为没有元素可以移出),并返回undef。 push push(@array,0); #@array 现在为(5,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) 12. 默认变量 $_ = "default variablen"; print; foreach (1..10) { ?? ?print "I can count to default value $_n"; } 13. context @people = qw (dd cc bb aa); print "people:n@peoplen"; @sorted = sort(@people); print "sorted:n@sortedn"; $number = @sorted; print $number."n"; 另一个例子是 reverse。在列表 context 中,它返回反转的列表。在标量 context 中,返回反转的字符串(或者将反转的结果串成一个字符串): @backwards = reverse qw / yabba dabba doo /; #返回 doo,dabba,yabba $backwards = reverse qw/ yabba dabba doo /; #返回 oodabbadabbay 让我们看看已经出现过的一些别的表达式及其 context。下面是一些标量 context: $fred = something; $fred[3] = something; 123 + something; something + 654 if(something){ ... } $fred[something] = something; 下面是一些列表 context: @fred = something; ($fred,$barney) = something; ($fred) = something; push @fred,something; foreach $fred(something) sort something reverse something print something @bamey = "this is ".' '."world"; foreach $s(@bamey) { ?? ?print $s."n"; }? #结果为: this is world @arr = qw [bb cc aa ee]; print "I have ".@arr." arrn"; #answer is: I have 4 arr print "I have ",@arr," arrn"; #answer is:I have bbccaaee arr print "I have ",scalar @arr," arrn";? #answer is: I have 4 arr 14. hash的定义使用 定义 my %some_hash = ("last_name","kelvin","first_name","liu"); 取值 $hash{$some_key} 赋值 $family_name{“ fred”} = flintstone; #my %some_hash = ("last_name","liu"); my %some_hash = ( "last_name" => "kelvin","first_name" => "liu" ); my @keys = keys %some_hash; my @values = values %some_hash; my @array = %some_hash; print @array."n"; #4 print "@array"."n";? #first_name liu last_name kelvin my $key; my $value; foreach $key(@keys) { ?? ?print $key."n"; } =cut ? my %some_hash = ( "last_name" => "kelvin","first_name" => "liu" ); my @keys = keys %some_hash; my @values = keys %some_hash; while ((my $key,my $value) = each %some_hash) { ?? ?print $key." and ".$value."n"; } foreach my $key2 (sort keys %some_hash) { ?? ?print "key = ".$key2.",value = ".$some_hash{$key2}."n"; } if (exists $some_hash{"first_name"}) { ?? ?delete $some_hash{"last_name"}; ?? ?my @keys3 = keys %some_hash; ?? ?foreach my $key4 (@keys3) ?? ?{ ?? ??? ?print "compare with $key4"."n"; ?? ??? ?if ($key4 eq "last_name") ?? ??? ?{ ?? ??? ??? ?print "this is $key4"."n"; ?? ??? ??? ?exit; ?? ??? ?} ?? ??? ?print "$key4 not equals last_namen"; ?? ?} } 15. regular expression:正则表达式 点(.)是通配符,它可以匹配任何单个的字符,但不包括换行符(“n”). 如果只希望点(.)匹配句号,可以使用反斜线。这条规则对 Perl 正则表达式中所有元字符均有效: 元字符前使用反斜线将使它变成普通的字符。如,模式/3.14159/中的点(.)即不是通配符。 可以这样看待星号(*): “前面的东西,重复任意次数,包括 0 次.只是前面 的一个字符,不是任意匹配。 将.*叫做“任意字符串匹配模式”,因为任意的字符串均能被匹配上 因为加(+)意指一个或多个,因此至少是一个。可以这样看待加(+): “最后一项,(可选的)至少还 有一项。 ” 问号(?),其含义是前面一个项出现一次,或者不出现。也就是说,前面这个项出现 1 次或者 0 次,此外不会有其它情况。因此,/barm-?bamm/只匹配:bamm-bamm 或 bammbamm。这很容易记住: “前面 的这个项,出现?或者不出现?” 模式/(fred)+/能匹配上像 fredfredfred 这样的字符串,这更可能是你所希望的。 那么模式/(fred)*/ 呢?它将匹配上像 hello,world 这样的字符串◆。 任何数字的类,[0-9],可以被简写为:d。 if(/HAL-[0-9]+/){ print “ string mentions some model of HAL computer.n” The ; } 例子可以被写作/HAL-d+/。 w 被称作 “ word’ 字符:[A-Za-z0-9_]。 w 不能匹配单词,而只能匹配单个字符。为了匹配整个单词,需要后接加号。模式 /fred w+ barney/将匹配 fred,空 格,一个“单词(word),然后是空格和 barney。因此,如果 fred 和 barney 之间有一个单词◆,由单个空格分隔开,它将 ” 能匹配上。 s 对于匹配空白(whitespace)将非常方便。它等价 于[ftnr ],其含 5 个空白字符:格式符(form-feed) ;制表符(tab),换行符,回车,以及空格符。 希望得到这三种简写形式的补集。如果那样的话,你可以使用[^d],[^w],和[^s],其含义分别是,非数 字的字符,非 word(记住我们对 word 的定义)的字符,和非空白的字符。也可以使用它们对应的大写形式:D,W,S 来 完成。它们将匹配它们对应的小写形式不能匹配上的字符。 /i 要创建一个大小写无关的模式,如匹配 FRED 时,也能匹配上 fred,Fred,可以使用修饰符 /i: if(/yes/i) {#大小写无关 print “ that case,I recommend that you go bowling.n” ; } /s 可以使用/s 这个修饰符。它将模式中点(.)◆的行为变成同字符类[dD]的行为类似:可以匹配任何字符,包括换 行符。 $_ = “ saw Barneyndown at the bowing alleynwith Frednlast night.n” ; if(/Barney.*Fred/s){ print “ That string mentions Fred after Barney!n” ; } 如果不使用/s,那么上述模式将不能被匹配上,因为这两个字符不在同一行中。 /x /x 修饰符,允许你在模式中加入任何数量的空白,以方便阅读: /-?d+.?d*/ #这是什么含义? / -? d+ .? d* /x #要好些 由于/x 允许模式中使用空白,那么模式中的空格,制表符将被忽略。可以在空格前加上反斜线或者使用t(许多方法中的一 种),但匹配空白更常用的方法是使用s(s*或s+)。 Perl 中,注释可以被作为空白,因此使用/x,可以在模式中加上注释: / -? #可选的负号 d+ #小数点前一个或多个十进制数字 .? #可选的小数点 d* #小数点后一些可选的十进制数字 /x #模式结束 ^ and $:开始结尾匹配 符号^(脱字字符◆)表示在字符串的开头进行匹配,而符号$则表示在结尾◆。因此,模式/^fred/只匹配字符串的开头部分; 它不会匹配上 manfred man。而/rock$/只在结尾处匹配;其不会匹配上 knute rockne。 一个经常使用的例子是/^s*$/,它将匹配一个空行(blank line) 。这 里的“ blank(空白)”,可以是空白符,如制表符,空格等,它们是不可见的。 锚定不仅仅针对字符串的两头。词界锚定,b,是针对单词使用的。如/bfredb/可以匹配上单词 fred,但不能匹配 frederick,alfred,man fred mann。这同字处理软件中的 “ 全字匹配(match whole words only)” 是类似的。 非词界锚定为B。它将在任何非b 匹配的点上进行匹配。因此,模式/bsearchB/将匹配 searches,searching,searched,但不能 匹配 search,或者 researching。 对$_进行匹配只是默认的行为,使用绑定操作符(=~)将告诉 Perl 将右边的模式在左边的字符串上进行匹配,而非对$_匹配。 例如: my $some_other = “dream of betty rubble.”; if($some_other =~ /brub/){ print “ Aye,there’ the rub.n” ; } 匹配上的那部分字符串将自动存储在$&之中。 $`中含有正则表达式引擎在匹配成功前所找到的变 量,而$'为此模式还没有匹配的剩余部分。如果将这三个变量放在一起,你将得到原始字符串: 模式/a{5,15}/将匹配 5 个到 15 个 a 中的任意一个(包括 5,和 15) 。如果 a 出现了 3 次,则次数太少,而不能匹配上; 如果省略掉第二个数字(逗号留下),现在没有上限了。 如果除了上限数字外,逗号也被省略了,那将匹配确定的次数. 星号(*)等同于{0,},表示 0 个或多个。加号(+)等同于{1,表示 1 个或多个。而问 号(?)则等同于{0,1}。 16. 循环控制语句 Last: last 会立刻结束循环。(这同C 语言或其它语言中的“break”语句类似)。它从循环块中“紧急退出”。当执行到last,循环即结束,如下例: #输出所有出现fred 的行,直到遇见_ _END_ _标记 while(<STDIN>){ if(/_ _ END_ _/){ #这个标记之后不会有其它输入了 last; }elsif(/fred/){ print; } } ##last 跳转到这里## next: 有时还不希望结束循环,但本次循环已经结束。这种情况下,next 是非常适用的。它跳到当前循环块的最后面(块内)◆。 next 之后,又会进入下一轮循环(这和C 或者类似语言的“continue”相似): #分析输入文件的单词 while(<>){ foreach(split){ #将$_分拆成单词,并依次赋给$_ $total++; next if/W/; #不是“words”的被跳过 $valid++; $count{$_}++; #对每个单词进行计数 ##next 跳到这里## } } print “total things = $total,valid words = $validn”; foreach $word (sort keys %count){ print “$word was seen $count{$word} time.n”; } redo: 循环控制的第三个操作是redo。它会调到当前循环块的顶端,不进行条件表达式判断以及接着本次循环。(在C 或类似语言中没有这种操作。)下面是一个例子: #输入测试 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.nn”; $errors++; redo; #跳转到循环顶端 } } print “You’ve completed the test,with $errors errors.n” 三元操作符:? my $size = ($width < 10 ) ? “small”: ($width < 20) ? “medium”: ($width < 50) ? “large”: “extra_large”; #default

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读