欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
Learning Perl



我的評價(jià):本書(shū)是perl的經(jīng)典入門(mén)書(shū)籍,介紹了perl中最基本的概念和語(yǔ)法,是perl入門(mén)的好書(shū),我向所有想了解或學(xué)習perl語(yǔ)言的朋友推薦本書(shū)。書(shū)中穿插有perl語(yǔ)法形成的歷史和原因,使你能充分感受到perl語(yǔ)言的文化,這也是perl流行的原動(dòng)力。本書(shū)行文流暢,各知識點(diǎn)介紹到位,令人很容易明白,達到入門(mén)點(diǎn)睛的效果。但本書(shū)的作用也就是入門(mén)而已,目的很明確,它沒(méi)有深入到perl腳本語(yǔ)言的高級部份。如果你想了解perl的高級功能或使用perl來(lái)更好地完成你的日常工作,還需進(jìn)一步學(xué)習,《perl語(yǔ)言編程》應該是你最好的選擇。第一章 簡(jiǎn)介第二章 標量數據什么是標量數據?標量(scalar)是perl中最基本的元素。大多數標量要么是一個(gè)數字,要么是一個(gè)字符串。perl基本上把它們視為可相互替換的東西。數字所有數字的內部格式都一樣在內部,perl一律把整數,浮點(diǎn)數按雙精度浮點(diǎn)數進(jìn)行計算。perl內部沒(méi)有整數值----程序中的一個(gè)整數常量被當作等值的浮點(diǎn)數。直接量(literal)指的是在perl源代碼中表示值的方式,浮點(diǎn)直接量	1.33,233.5,-3.9整數據直接量	0,89,-66,61_383_883_897_363(一個(gè)大數,用下劃線(xiàn)以示清晰)非十進(jìn)制整數直接量八進(jìn)制直接量以0開(kāi)頭十六進(jìn)制直接量以0x開(kāi)頭二進(jìn)制以0b開(kāi)頭從5.6版本開(kāi)始,perl允許在直接量中加下劃線(xiàn)以示清晰。0x50_65_7c數值操作符加	+	2 + 3減	-	3 - 2乘	*	2 * 3除	/	2/3模	%	10%3指數	**	2**3字符串單引號字符串直接量	在引號間除了單引號或反斜杠以外的任何字符(包括換行符,如果該字符串連續占幾行)在字符串中表示該字符本身。要想得到一個(gè)斜杠,需要連續寫(xiě)兩個(gè)斜杠,要得到一個(gè)單引號,需要加一個(gè)斜杠。雙引號字符串直接量	在雙引號內的反斜杠開(kāi)始發(fā)揮它的作用,可以用來(lái)指定特定的控制字符??梢栽陔p引號里面內插變量。雙引號內的轉義字符完整列表\n	換行\r	回車(chē)\t	制表符\f	換頁(yè)\b	退格\a	響鈴\e	Esc(ascii的轉義字符)\007	任意ASCII碼的八進(jìn)制值(這里007=響鈴)\x7f	任意ASCII碼的十六進(jìn)制值(這里07f=刪除)\cC	任意Ctrl鍵組合字符(這里是Ctrl-C)\\	反斜杠\"	雙引號\l	下一個(gè)字母小寫(xiě)\L	所有后面的字母小寫(xiě),直到\E\u	下一個(gè)字母大寫(xiě)\U	所有后面的字母大寫(xiě),直到\E\Q	添加反斜杠引用后面的非單詞字符,直到\E\E	結束\L,\U,\Q字符串操作符.	連接兩個(gè)字符串		"hello" . "world"   =   "helloworld"x	串重復操作符	"yang" x 3="yangyangyang"    次數使用前截成一個(gè)整數。4.8=4,小于1的拷貝次數會(huì )得到一個(gè)空串。數字與字符串的自動(dòng)轉換依賴(lài)于作用在標量值上的操作符。如果是+則是數據,如果是.則是字符串。"z".6*7="z42" ,"12"*"3"=36perl的內置警告可以要求perl在發(fā)現你程序有異常時(shí)給你一個(gè)警告。使用 -w 選項。#!/usr/bin/perl -w標量變量變量(variable)是一個(gè)容器的名字,用以存放一個(gè)或多個(gè)值,變量的名字在程序中保護不變,但它所包含的值在執行過(guò)程中一般要不停地改變。在perl中用美元符號標識。$a,$test。選擇好的變量名適當加一些下劃線(xiàn)可讓變量更易讀,更易理解。標量賦值(assignment)操作符用等號,它的左邊是變量名,右邊是值。二元賦值操作符+=	-=	*=	.=	**= and so on用print輸出print "hello world\n";print "the answer",6*6,".\n";在字符串中替換標量變量$meal = "brontosaurus steak";$barney = "fred ate a $meal";   另一種寫(xiě)法  $barney = ‘fred ate a‘.$meal;如果標量變量從未被賦過(guò)值,就用一個(gè)空串替換。操作符優(yōu)先級和結合性善用小括號perlk中的操作符優(yōu)先級和結合性與C一樣比較操作符相等		==	eq不相等		!=	ne小于		<	lt大于		>	gt小于等于	<=	le大于等于	>=	geif控制結構if () {...;} else {...;}布爾值perl中沒(méi)有單獨的的布爾數據類(lèi)型,不過(guò),它使用幾條簡(jiǎn)單的規則。1、特殊值undef是假。2、0是假,所有其它的數字是真。3、空串‘‘是假,所有其它的字符串一般是真。4、一個(gè)例外,因為數字和字符是等價(jià)的,所以0的字符形式‘0‘,和它的數值形式有同樣的值:假。! 是取反的意思,可以在真值前加,結果就變成了假。取得用戶(hù)輸入<STDIN>從鍵盤(pán)得到一個(gè)值。一般以\n字符結束。所以可利用該字符做條件控制。chomp操作符它作用于一個(gè)變量,此變量必須存放一個(gè)字符串,如果這個(gè)字符串以換行符結尾,chomp就把它去掉。$text = "a line of text\n";chomp ($text);	去掉換行符chomp($text =<STDIN>);	最常用的方法,讀文本,不帶換行符chomp是一個(gè)函數,所有它有返回值,即去掉的字符個(gè)數。使用chomp時(shí)可以帶或不帶小括號,這是perl的另一個(gè)基本規則,除非去掉括號會(huì )改變意思,否則括號總是可有可無(wú)的。while控制結構重復執行一個(gè)代碼塊,只要條件為真。$count = 0;while ($count < 10 ) {$count +=1;print "count is now $count\n";	得到從1到10的值。}undef值變量在第一次賦值之前有特別的undef值,代表什么也沒(méi)有。當把它作為字符串時(shí),其功能相當于一個(gè)空串。當把它作為數字時(shí),其功能相當于0。perl程序員經(jīng)常這樣使用。很多操作符在操作數超出范圍或沒(méi)有意義時(shí)會(huì )返回undef值,這樣一般不是什么問(wèn)題,但如果打開(kāi)perl的警告,則會(huì )導至一個(gè)警告。defined函數測試一個(gè)值是undef還是非空字符串,可以使用這個(gè)函數。它對undef返回假,其它所有情況則返回真:$madon = <STDIN>;if (defined($madon) {print "the input was $madon";} else {print "no input available!\n";}如果你想生成自已的undef值,可以用古怪的undef操作符$madon = undef;		好像它從來(lái)沒(méi)有被動(dòng)過(guò)第三章 列表和數組在perl中,如果“單數”是標量,那么“復數”則由列表和數組來(lái)表示。列表(list)是一個(gè)有序的標量集合,數組(array)是一個(gè)包含列表的變量。精確地說(shuō),列表是數據,而數組是變量,可以有一個(gè)不在數組的列表,但每個(gè)數組變量都包含一個(gè)列表。數組和列表可以放任意多的元素,最小的是沒(méi)有元素,而最大的可以把所有內存耗盡。這符合perl的“沒(méi)有不必要的限制”哲學(xué)。訪(fǎng)問(wèn)數組的元素數組元素用連續的整數編號,從0開(kāi)始,然后按1遞增。$fred[0] = "a";$fred[1] = "b";$fred[2] = "c";如果下標所指的元素超出了數組的區間,那么相應的值就是undef。特殊的數組索引如果你試圖存儲一個(gè)超出數組區間的數組元素,這個(gè)數組就會(huì )自動(dòng)按需擴展,對它的長(cháng)度沒(méi)有限制,只要有足夠的內存供perl使用。$rocks[0] = "a";$rocks[1] = "b";$rocks[2] = "c";$rocks[10] = "end";   現在就有6個(gè)undef元素。訪(fǎng)問(wèn)最后一個(gè)元素的索引是$#rocks。負的數組索引從數組尾部算起,-1代表最后個(gè)元素。列表直接量列表直接量(list literal)是小括號中的一列由逗號分隔的值。例如:(1,2,3,4)   (“fred”,43.4)  ()  (1..100)  (0..$#rocks)“..”是區間操作符,能生成一個(gè)順序列表。如上例中的從1到100。列表可包含表達式或變量。qw快捷方式qw表示“被括引的單詞”(quoted words)或“用空白括住”(quoted by whitespace),perl按單引號字符串處理它們,所以你不能像在雙引號字符串中那樣在qw列表中用\n或$fred)。qw /a b c d/    等同于   ("a","b","c","d")qw !a b c d!    等同于   ("a","b","c","d")qw {a b c d}    等同于   ("a","b","c","d")定界符可以選擇任意的標點(diǎn)。列表賦值($fred,$barney,$dino) = ("a","b","c")($fred,$barney) = ($barney,$fred)     交換它們的值,比c等語(yǔ)言方便很多。如果變量的個(gè)數小于值的個(gè)數,則多余的值會(huì )被無(wú)聲地忽略。如果變量的個(gè)數多于值的個(gè)數,則多的變量會(huì )得到undef值。at符號@可以一次指定整個(gè)數組。這樣@rocks代表“所有的rocks”。@rocks = qw / a b c/;@copy = @quarry      從一個(gè)數組拷貝一個(gè)列表到另一個(gè)數組pop and push操作符正真的perl程序員不使用索引訪(fǎng)問(wèn)數組,這樣發(fā)揮不了perl的強項。我們經(jīng)常把數組當信息棧用??偸菑牧斜淼挠覀燃尤胄轮祷騽h除。pop操作取出一個(gè)數組的最后一個(gè)元素@array = 5..9;$fred = pop(@array);	$fred得到9,@array現在有(5,6,7,8)$barney = pop(@array);	$barney得到8,@array現在有(5,6,7)如果數組是空的,pop就不管它,因為沒(méi)有元素可刪除,只返回undef。push操作與pop對應,它順數組的最后添加一個(gè)元素或一個(gè)元素列表。push(@array,0);		@array現在有(5,6,7,0)@others = qw /1 2 3/;push @array,@others	@array現在有(5,6,7,0,1,2,3)注意:push的第一個(gè)參數或pop的唯一參數必須是一個(gè)數組變量,進(jìn)棧和出棧對直接量列表來(lái)說(shuō)是沒(méi)有意義的。shift and unshift 操作類(lèi)似于push and pop,shift and unshift對數組的頭部進(jìn)行相應的操作。在字符串中替換數組與標量一樣,數組的值也可以被替換到雙引號字符串中。print "quartz @rocks limestone\n";  打印所有巖石,用空格分開(kāi)。注意:不要把電子郵件地址放到雙引號字符串中。foreach控制結構foreach循環(huán)遍歷列表中的所有值,對每個(gè)值執行一個(gè)迭代(執行一次循環(huán)體)foreach $rocks ( qw /a b c/) {print "one rock is $rocks.\n";	打印a b c。}Perl最喜歡的缺省變量:$_如果你在foreach循環(huán)的開(kāi)始忽略了控制變量,perl就會(huì )使用$_。foreach (1..10) {		缺省使用$_print "I can count to $_!\n";}$_ = "a";print;   缺省打印$_reverse操作符reverse 取一個(gè)列表的值,然后返回相反順序的列表。記住它只返回反序列表,并不影響它的參數,如果返回值不被賦給別的變量,它是不保存。sort操作符sort取一個(gè)列表的值,然后按照內部字符序進(jìn)行排序。標量和列表上下文一個(gè)給定的表達式在不同的地方,可能會(huì )有不同的含義。5 + something 		something必須是個(gè)標量sort something 		something必須是個(gè)列表在標量上下文中使用列表生成表達式提供標量上下文的表達式:$fred = something;$fred[3] = something;123 + somethingsomething +654;if (something) {...}while (something) {...}$fred[something] = something;提供列表上下文的表達式:@fred = something;($fred,$barney) = something;($fred) = something;push @fred,something;foreach $fred (something) {...}sort something;reverse something;print something;在列表上下文中使用標量生成表達式如果一個(gè)表達式在正常情況下不生成一個(gè)列表值,那么自然它就會(huì )生成標量值,即一個(gè)元素列表:@fred = 6*7 	得到一個(gè)單元素列表(42)注意,因為undef是個(gè)村標量值,所以給一個(gè)數組賦undef并不能清空數組,清空的更好方法是賦一個(gè)空列表()。強制使用標量上下文可以使用scalar假函數,它告訴perl提供一個(gè)標量上下文。@rocks = qw /a b c d/;print "i have",@rocks,"rocks!\n";		錯,打印了石頭的名字print "i have",scalar @rocks,"rocks!\n";	正確,打印石頭的數量列表上下文中的<STDIN>chomp (@lines = <STDIN>);	讀入那些行,不帶換行符第四章 子例程系統與用戶(hù)函數perl的子例程可以讓我們在一個(gè)程序中重復利用一塊代碼,子例程名字是在前面加一個(gè)可有可無(wú)的&符號,有一條規則規定什么時(shí)候可以省略。定義一個(gè)子例程使用關(guān)鍵字sub和子例程名定義??梢苑旁诔绦虻娜魏挝恢?。sub marine {$n += 1;print "hello ,sailor number $n!\n";}注意:n 為全局變量調用子例程$marine;	輸出hello,sailor number 1!$marine;	輸出hello,sailor number 2!返回值每個(gè)子例程在運行過(guò)程中,計算值是它一系列動(dòng)作的一部份。在子例程中得到的最后一個(gè)計算值自動(dòng)成為返回值。因此注意在向子例程增加代碼時(shí)要確保最后一個(gè)表達式的結果是你希望的返回值?!白詈笠粋€(gè)表達式”是指真正的、被最后計算的表達式,而不是正文的最后一行。參數參數列表在子例程運行期間被自動(dòng)地賦給一個(gè)特別的數組變量@_。子例程可以訪(fǎng)問(wèn)這個(gè)變量以確定參數個(gè)數和參數的值。也就是說(shuō),第一個(gè)參數被存在@_[0],第二個(gè)被存在@_[1]中,其它依次類(lèi)推。@_變量是子例程的局部變量,如果@_中有一個(gè)全局變量,它就會(huì )在子例程調用前被保存起來(lái),而在子例程返回時(shí)恢復原值。子例程中的私有變量my操作符生成被稱(chēng)為詞法變量(lexical variable)的私有變量。local操作符local的真正功能是把給定的變量的一個(gè)拷貝保存在一個(gè)秘密的地方(棧)。這個(gè)值在保存后不能被訪(fǎng)問(wèn)、修改、刪除,讀出、檢查、打印等。在perl中沒(méi)有辦法以接近被保存的值。接著(zhù)local把該變量設為空值(對標量是undef,對數組是空表),或設為任何賦給它的值。當perl從子例程中返回時(shí),會(huì )自動(dòng)將變量恢復為原先的值。從效果上來(lái)看,這個(gè)變量被暫時(shí)借用了片刻。local 和 my 的區別local是全局變量,可以想成“save”(在子例中調用時(shí)),在所有新代碼中只用my,my比local快??勺冮L(cháng)參數列表在perl中,經(jīng)常傳遞給子例程任意長(cháng)度的參數列表。子例程可以查看@_數組,從而輕松地判斷參數的個(gè)數。但在實(shí)際的perl編程中,這類(lèi)檢查幾乎沒(méi)有用過(guò),最好是讓子例程適應參數。一個(gè)允許任意參數的例程$maximum = &max(3,5,10,4,6);sub max {my ($max_so_far) = shift @_;foreach (@_) {if ( $_ > $max_so_far) {$max_so_far = $_;}}$max_so_far;}這段代碼使用了被稱(chēng)作“高水位線(xiàn)(high-water mark)的算法。在一次洪水之后,當水最后一次漲潮和退潮時(shí),高水位線(xiàn)顯示了曾經(jīng)達到的最高水位??盏膮盗斜矸祷匾粋€(gè)undef。詞法(my)變量的說(shuō)明my可以在任何塊中使用,而不僅僅在子例程中。例如可以在if,while or foreach中。use strict pragmaperl是一種特別寬松的語(yǔ)言,但也許你想讓perl把規則加強一些,這可以用user strict pragma(編譯指示)來(lái)安排。pragma中給編譯器的提示,告訴它關(guān)代碼的一些信息,這里,use strictpragma是告訴perl編譯器,它應該在本塊或源文件的其余部份強制使用一些好的程序設計規則。return操作符該操作符立即從子例程中返回一個(gè)值。省略與字符(&)原則在除與內置函數名一致,其它子例程都可以省略與字符。第五章 散列什么是散列?散列(hash)是一個(gè)數據結構,與數組相同的是它可以含有任意數目的值并隨意讀取它們。但與數組中由數字對值進(jìn)行索引不同,散列用名字(name)查找值。也就是說(shuō),索引不再是數字,而是任意的惟一字符串,稱(chēng)之為鍵(key)。它是一桶數據,不存在第一項,它是一團糟的,隨意的,沒(méi)有固定的順序。鍵總是被轉成字符串,如用數值50/20做鍵,它就會(huì )被變成“2.5”。散列可以任意大小,從空散列直以填滿(mǎn)內存。在perl中巨大的散列并不可怕,從三個(gè)和三百萬(wàn)個(gè)鍵值對中取出一個(gè)數的速度差不了多少。為什么要用散列你有一組數據與另外一組數據相關(guān)。如名		姓主機名		ip地址ip地址		主機名單詞		單詞出現的次數用戶(hù)名		用戶(hù)使用的硬盤(pán)塊數駕照號碼	名字如果你的任務(wù)描述中包含“找到重復項”,“唯一的”,“交叉引用”,或“查表”之類(lèi)的詞語(yǔ),那么散列就會(huì )在實(shí)現中很有用處。散列元素訪(fǎng)問(wèn)使用如下語(yǔ)法:$hash{$some_key}$a{"home"} = "first";$a("hotel"} = "second";當你在一個(gè)已存在的散列中存入東西時(shí),會(huì )覆蓋以前的值。訪(fǎng)問(wèn)散列之外的元素會(huì )得到undef:$a = $b{"test"};	這里沒(méi)有test,得到undef。作為一個(gè)整體的散列要訪(fǎng)問(wèn)整個(gè)散列,就使用%號做前綴。為方便起見(jiàn),可以將散列轉換為一個(gè)列表,并轉換回來(lái),給散列賦值是一個(gè)列表上下文,這個(gè)表由鍵-值對組成%hash = ("aa",33,"bay",11,2.5,"hello","cc","bb\n");展開(kāi)散列(unwind),把散列轉換回鍵-值對應列表。次序亂了,但鍵-值還是成對出現的。@array = %hashprint "@array";bay,11,2.5,hello,cc,bb(一個(gè)換行符),aa,33散列賦值%new_hash = %old_hash			perl將%old_hash展開(kāi)成一個(gè)鍵-值對列表,并賦值給%new_hash。%inverse_hash = reverse %any_hash	生成逆散列,鍵變值,值變鍵。前提是原散列值要唯一。大箭頭用大箭頭把散列中的鍵-值對組織起來(lái)。my %hash = ("aa" => "test1","bb" => "test2","cc" => "test3",	最后額外的逗號是無(wú)害的);散列函數keys函數得到一個(gè)散列中所有當前鍵構成的一個(gè)列表,values函數得到一個(gè)相應的值。my %hash = ("a" => "test1,"b" => "test2","c" =>"test3");my @k =	 keys %hash		得到"a","b","c"。my @v = values %hash		得到"test1","test2","test3"。在一人標量上下文中,這些函數給出散列的元素個(gè)數。my $count = keys %hash		得到3,即有三個(gè)鍵-值對。each函數該函數可以遍歷一個(gè)完整的散列。每次返回一個(gè)鍵-值對作為一個(gè)二元元素列表。最后返回一個(gè)空列表。while ( ($key,$value) = each %hash ) {print "$key => $value\n";}exists函數查看某鍵是否在散列中。存在就返回真,不存在就返回假。delete函數從散列中刪除指定的鍵(和相應的值)。如無(wú)此鍵,它的任務(wù)就結束。此時(shí)沒(méi)有警告或出錯信息給出來(lái)。第六章 I/O基礎從標準輸入進(jìn)行輸入while (defined($line = <STDIN>)) {print "I saw $line";};因為行輸入操作符在你到達文件末尾時(shí)會(huì )返回undef,所以可以用它方便地跳出循環(huán)。從鉆石操作符進(jìn)行輸入“<>”是一種特殊的行輸入操作符,它可以是也可以不是來(lái)自鍵盤(pán)的輸入。while (defined($line = <>)) {chomp($line);print "It was $line that I saw!\n";};如果用a,b,c三個(gè)參數調用該程序,將打印三個(gè)文件的內容。使用鉆石操作符,就好像輸入文件被合并到一個(gè)大文件中。上面程序可用快捷方式寫(xiě)成:while (<>) {chomp;print "It was $_ that I saw!\n";};大多數linux標準工具中,短橫-代表標準輸入流。通常在一個(gè)程序中只用一個(gè)鉆石操作符,當初學(xué)者在程序中放第二個(gè)鉆石時(shí),其實(shí)他們一般是想用$_。記住,鉆石操作符讀取輸入,但輸入本身是在$_中。調用參數鉆石操作符并不是直接從字面上讀取調用參數,它實(shí)際上讀取@ARGV數組。它被perl解釋器預設為調用參數的列表。在程序中可以對該數組進(jìn)行賦值等操作。@ARGV = qw# a b c #;	強制讀取這三個(gè)文件while (<>) {chomp;print "It was $_ that I saw!\n";};向標準輸出進(jìn)行輸出print @array;		aabbccprint "@array";		aa bb ccprint <>;		cat 的源代碼print sort <>;		sort 的源代碼用printf進(jìn)行格式化輸出,和c類(lèi)似。數組與printf可動(dòng)態(tài)形成格式字符串。my @items = qw ( a b c );my $format = "the items are:\n".("%10s\n" x @items);	在標量上下文中使用@items得到它的長(cháng)度printf $format,@items		在列表上下文中使用@items得到它的內容上下文太重要了。要好好感受。第七章	正則表達式的概念正則表達式(regular expression),在perl中經(jīng)常被稱(chēng)為模式(pattern),是與一個(gè)給定字符串匹配或不匹配的模版。不要把正則表達式和被稱(chēng)為glod的shell的文件名匹配模式混淆。比如*.pm匹配以.pm結尾的文件名。使用簡(jiǎn)單的模式要比較一個(gè)模式和$_的內容,只需把模式放在一對斜杠之間,如下:$_ = "aabbkdkdk";if ( /aabb/ ) {print "it matched!\n";};關(guān)于元字符在正則表達式中有一組具有特殊意義的字符,叫元字符,如:.號匹配任意單個(gè)字符(但不匹配換行符),加反斜杠會(huì )使它不再特殊。一對反斜杠配置一個(gè)真正的反斜杠。簡(jiǎn)單的數量符在模式中重復一些東西。*號匹配前面的條目0次或多次。如:/foo\t*test/匹配在foo和test間任意數目的制表符。.*	匹配任意字符、任意次數。+	匹配前面的條目一次或多次。?	匹配前面的條目是可選的,只能發(fā)生一次或0次(即沒(méi)有)。模式中的分組可以用()括號分組,所以小括號也是元字符。如:/abc+/		匹配abccccccccccccccccc/(abc)+/	匹配abcabcabcabcabc/(abc)*/	匹配任意字符串,甚至是空串。選擇豎線(xiàn) | 表示要么是左側匹配,要么是右側匹配。此時(shí)讀做“或”。/aa|bb|cc|/		匹配一個(gè)含有aa或bb或cc的字符串。/aa( |\t)+bb/		匹配aa和bb中間被空格、制表符或兩者的混合串分隔/aa( +|\t+)bb/		匹配aa和bb中間必須全是空格,或全是制表符/aa(and|or)bb/		匹配aa and bb 和aa or bb一個(gè)模式測試程序下面這個(gè)程序有助于在一些字符串上測試一個(gè)模式,看看它匹配了什么,在哪里匹配的。#!/usr/bin/perlwhile (<>) {chomp;if (/your_pattern_goes_here/) {print "Matched : |$`<$&>$‘|\n";} else {print "No match.\n";}};第八章 正則表達式提高字符類(lèi)字符類(lèi)(character class)即在一對中括號中列出的所有字符,可以匹配類(lèi)中的任何單個(gè)字符。例如:[abcdefg]可以匹配這七個(gè)字符中的任何一個(gè)??捎谩?”指定一個(gè)范圍。如[a-h],[1-9]等。[\001-\177]匹配任何7比特ASCII碼。中括號中的“^”號是取反的意思,如[^abc]匹配除abc外的任何單個(gè)字符。字符類(lèi)快捷方式有些字符類(lèi)的使用特別頻繁,所以就有了快捷方式。如:所有數字的字符類(lèi)[0-9]可以縮寫(xiě)成\d,[A-Za-z0-9_]縮寫(xiě)成\w。\s匹配空白,它和[\f\t\n\r ]等同,即等同一個(gè)含五種空白字符的字符類(lèi),它們是換頁(yè)符,制表符,換行符,回車(chē)符和空格字符自已。\s只匹配類(lèi)中的一個(gè)字符,所以一般用\s*匹配任意數量的空白(包括沒(méi)有空白),或用\s+匹配一個(gè)或多個(gè)空白字符。以上快捷方式的反置寫(xiě)法是用大寫(xiě)形式表示,\D,\W,\S。/[\dA-Fa-f]/匹配十六進(jìn)制數字。/[\d\D]/匹配任何數字或任何非數字,也就是任何字符,包括換行符?!?”匹配除換行符外的所有字符。/[^\d\D]/表示什么都不匹配。通用數量符前面我們見(jiàn)過(guò)三個(gè)數量符*,+,?。但如果這三個(gè)不能滿(mǎn)足你的需要,也可以用大括號{}中的一對由逗號隔開(kāi)的數字來(lái)指定重復的最少和最多次數。如/a{5,15}/匹配重復5次到15次的字母a。如果省略第二個(gè)數(但包含逗號),那么匹配的次數就沒(méi)有上限。如/a{3,}/就匹配一行中連續出現的3個(gè)或多個(gè)a,它沒(méi)有上限。如果連逗號也沒(méi)有了,那么給出的數字就是一個(gè)準確的數字。如/a{3}/匹配3個(gè)a。*	等價(jià)  {0,}+	等價(jià)  {1,}?	等價(jià)  {0,1}錨位符錨位符(anchor)可以用來(lái)為模式指定字符串的特定位置?!癪”標志字符串的開(kāi)頭,“$”標志字符串的結尾。如/^a/匹配處于字符頭的abc,不能匹配dda,/b$/匹配處于字符尾的aab,不能匹配abc。/^s*$/匹配一個(gè)空行/^abc$/匹配abc,又匹配abc\n單詞錨位符\b可以匹配一個(gè)單詞的兩端,可以用/\babc\b/來(lái)匹配單詞abc??梢杂靡粋€(gè)單詞錨位符,如,/\bth/可以匹配this,these,但不匹配method。/er\b/匹配hander,woner,但不匹配gerenic,lery.非單詞邊界錨位符是\B,它匹配任何\b不匹配的地方。如/\bsearch\B/會(huì )匹配searches,searchingand searched.但不能匹配search or researching。記憶的小括號()可以用來(lái)把模式的一些部份組合起來(lái),它還有第二個(gè)功能,它們要求正則表達式引擎記住與小括號中的模式匹配的那部份子串。反向引用反向引用(backreference)就是回頭引用在當前模式處理過(guò)程中保存的記憶。用一個(gè)么斜杠來(lái)構成,如\1包含第一個(gè)正則表達式記憶。即被第一對小括號匹配的字符串部份。反向引用被用來(lái)匹配與模式在前面匹配的字符串完全一樣的字符串。所以/(.)\1/匹配任意單個(gè)字符,在記憶1中記住它,然后再與記憶1匹配。換句話(huà)說(shuō),它匹配任意字符,后跟同一個(gè)字符。這樣,這個(gè)模式會(huì )匹配雙字母式的字符串。如bamm-bamm和betty。它和/../不一樣,/../匹配任意字符,后跟任意字符,它們兩個(gè)可以一樣,也可以不一樣。記憶變量正則表達式記憶的內容在模式匹配結束后仍可通過(guò)特殊變量$1得到。優(yōu)先級分四個(gè)級別1、最上面的是小括號。2、是數量符,*,+,?,{1,2},{1,},{1}3、是錨位符和序列,^,$,\b,\B。4、是堅線(xiàn) | 。優(yōu)先級例子/^aaa|bbb$/可能不程序員的意思,它只匹配字符串a(chǎn)aa的開(kāi)頭或字符串bbb的未尾。程序員更可能想要的是/^(aaa|bbb)$/,它匹配一行中沒(méi)有其它東西,除了aaa或bbb以外。第九章 使用正則表達式使用m//進(jìn)行匹配一對斜杠實(shí)際上是m//(模式匹配)操作符的一個(gè)快捷方式。如我們在qw//中所中,你可以選擇任何定界符對把內容括住。如m<aaa>,m(aaa),m{aaa},m[aaa],m!aaa!等。如果選擇了反斜杠,就可以省略m。選項修飾符用/i進(jìn)行不區分大小寫(xiě)的匹配。用/s進(jìn)行任何字符的匹配,包括換行符。它把模式中的每個(gè)點(diǎn)變成和字符類(lèi)[\d\D]一樣,匹配任何字符,包括換行符??山M合使用修飾符/is,順序并不重要。綁定操作符=~my $some_other = "I dream of betty rubble";if ($some_other =~ /\brub/) {print "Aye,there‘s the rub.\n";}看起來(lái)像個(gè)賦值語(yǔ)句,但它不是的。它是說(shuō)“這個(gè)模式缺省時(shí)匹配$_中的東西---但現在讓它匹配左側的字符串”。如果沒(méi)有綁定操作符,表達式就缺省使用$_。匹配變量可以用$1,$2,$3,$4引用正則表達式記憶的第一到第四個(gè)記憶。匹配變量是正則表達式強大功能的一個(gè)重要部份,它能讓我們取出一個(gè)字符串的一部份。$_ = "hello there,neighbor";if (/\s(w+),/) {			記住空格和逗號之間的單詞print "the word was $1\n.";      $1 就是 there}匹配變量可以是空串。記憶的持久性匹配變量一般保留到下一次模式匹配成功。也就是除非匹配成功,否則你不應該使用這些匹配變量。自動(dòng)匹配變量$&	實(shí)際與模式匹配的那部份字符串就保存在這里。if ("hello there, neighbor" =~ /\s(w+),/) {print "that actually matched ‘$&‘.\n";}整個(gè)匹配部份是" there,"(一個(gè)空格,there,一個(gè)逗號),$1中是there,而$&中是整個(gè)匹配部份。匹配部份之前的東西被存在$`,之后的東西被存在$‘。也就是說(shuō),$`含有正則表達式引擎在找到匹配之前需跳過(guò)的部份,而$‘則含有模式?jīng)]有到達的字符串的剩余部份。如果把這三個(gè)字符串按順序連在一起,那么你總會(huì )得到原字符串。第七章的模式測試程序就是使用了這三個(gè)神秘代碼。print "match:|$`<$&>$‘|\n"使用自動(dòng)匹配變量的代價(jià)是,會(huì )使用其它正則表達式的運行會(huì )變得慢一些。所以很多perl程序員都盡量避免使用這些自動(dòng)匹配變量。相反,他們會(huì )采用一些方法,例如,如果你只需要$&,那就在整個(gè)模式的周?chē)右粚ㄌ?,然后使?1。用s///進(jìn)行查換并替換$_ = "he‘s out bowling with barney tonight.";s/barney/killer;	用killer替換barney,如果匹配失敗,什么也不會(huì )發(fā)生。print "$_\n";s///有一個(gè)返回值,替換成功,則為真,否則為假。用/g進(jìn)行全局替換s///只替換一處,/g修飾符告訴s///進(jìn)行所有可能的無(wú)交迭替換。全局替換的一個(gè)相當常見(jiàn)的使用是壓縮空白,把任意數量的空白變成一個(gè)空格。s/\s+/ /g;	壓縮空白s/^\s+//;	把前面的空白刪除s/\s+$//;	把結尾的空白刪除s///也可用不同的定界符,如#,!號等,但如果使用成對的字符,因為它有左右之分,所以必須用兩對,一結放模式,一對放替換串,如s[aaa][bbb],s(aaa)(bbb),甚至也可以用s<aaa>(bbb)這樣不成對的定界符。s///也和m//一樣,有/i,/s修飾符和=~綁定操作符。$file_name =~ s/^.*///s;	在$file_name中,去掉所有unix風(fēng)格的路徑。大小寫(xiě)轉換\U	強制后面的字符都用大寫(xiě)	s/(aaa|bbb)/\U$1/gi     AAA BBB\L	強制后面的字符都用小寫(xiě)	s/(aaa|BBB)/\L$1/gi	aaa bbb用\E關(guān)閉,當寫(xiě)成小寫(xiě)形式時(shí),\u,\l就只影響下一個(gè)字符。\u\L或\L\u	代表首字符大寫(xiě),與順序無(wú)關(guān)。split操作符它把一個(gè)字符串按照分割子(separator)分開(kāi)。@fields = split /:/,"abc:def::a:b";	得到("abc","def","","a","b")。@fields = split /:/,":::a:b:c:::";	得到("","","","a","b","c"),結尾空字段被丟棄。在空白處分割也是常見(jiàn)的,使用/\s+/模式。split的缺省行為是在空白處分割$_。如my @fields = split;	等同于split /\s+/, $_;join函數在某種意義上,join完成split的相反過(guò)程。它把一組片斷粘合起來(lái)形成一個(gè)字符串。my $a = join ":",1,2,3,4,5;	則$a 是"1:2:3:4:5"join可以和split配合使用,把一個(gè)字符串分割后用不同的定界符恢復它。如可以把1,2,3 變成 1-2-3.第十章 更多的控制結構unless控制結構if是表達式為真時(shí)執行,如果希望表達式為假時(shí)執行可用unless(除非)。表示除非表達式為真,否則運行這個(gè)代碼。它就像一個(gè)具有相反條件的if語(yǔ)句,也可以理解成一個(gè)獨立的else子句。unless ($aa = ~/^[A-Z_]\w*$/i) {print "the value of \$aa doesn‘t look like a perl identifier name.\n";}等同于if ($aa =~ /^[A-Z_]\w*$/i) {} else {print "the value of \$aa doesn‘t look like a perl identifier name.\n";}等同于if (!$aa =~ /^[A-Z_]\w*$/i) {print "the value of \$aa doesn‘t look like a perl identifier name.\n";}以上語(yǔ)句都被編譯成相同的內部字節碼,但unless最自然。unless的else子句unless ($aa =~/^(bb)/) {print "this value like bb.\n";} else {print "do you see what‘s going on here?\n";}等同于if ($aa =~/^(bb)/) {print  "do you see what‘s going on here?\n";} else {print "this value like bb.\n";}until控制結構while的反置結構。until ($a > $b) {$a *= 2;}這個(gè)循環(huán)一直執行,直到條件表達式返回真為止。表達式修飾符print "$n is a negative number.\n" if $n < 0;等同于if ($n < 0) {print "$n is a negative number.\n";}前一種寫(xiě)法更緊湊。讀起來(lái)很像自然英語(yǔ)。還有:print " ",($n +=2) while $n < 10;$i *= 2 until $i >$j;&greet($_) foreach @person;裸塊控制塊所謂的“裸(naked)塊”,指的是沒(méi)有關(guān)鍵字或條件的塊。如:while (condition) {body;body;body;}現在把while關(guān)鍵字和條件去掉,就得到一個(gè)裸塊。{body;body;body;}它只執行一次,然后就結束,其中一個(gè)作用是提供一個(gè)臨時(shí)詞法變量的作用域。一條通用的原則,所有變量就應該在最小的作用域中聲明。如果你需要一個(gè)只用在幾行代碼中的變量,那么你可以把這些行放在裸塊中,并在該塊中聲明這個(gè)變量。elsif子句如果你需要檢查一組條件,一個(gè)接一個(gè),看看哪個(gè)條件為真,就可以用elsif子句(注意不是elseif)。perl會(huì )逐個(gè)測試條件表達式,當一個(gè)條件成功就執行相應的代碼。但如果測試項太多,就不要使用這種方式,應該用類(lèi)“case or switch”的語(yǔ)句。自遞增和自遞減++	$a++;	$a值不變。++$a;	把$a增1,存到$a里。--	$a--;	$a值不變。--$a;	把$a減1,存在$a里。for控制結構for ($i =1 ;$i <=10;$i++) {print "I can count to $i!.\n";}for ($_ = "aaabbbccc";s/(.)//; ) {	當s///成功時(shí)執行循環(huán)。print " one character is :$1\n."}每次迭代時(shí)都會(huì )去掉一個(gè)字母。當字符串為空時(shí),替換失敗,循環(huán)結束。以下用for實(shí)現的無(wú)限循環(huán)for (;;) {print "this is an infinite loop.\n";}以下為用while實(shí)現的無(wú)限循環(huán),一種更具perl特色的寫(xiě)法。while (1) {print "this is an infinite loop.\n";}foreach和for之間的秘密聯(lián)系在perl內部,foreach 和 for 完全等價(jià)。for (1..100) {				實(shí)現是一個(gè)從1到100的foreach循環(huán)print "I can count to $_.\n";}在perl中,foreach總是被寫(xiě)成for,因為可節省4個(gè)字符的輸入,因為懶惰是perl程序中的經(jīng)典品質(zhì)。循環(huán)控制last操作符	立即終止一個(gè)循環(huán)的執行(與c中的break相似)。作用于當前運行的最內層循環(huán)塊。next操作符	控制從循環(huán)的下一個(gè)迭代繼續(與c中的continue相似)redo操作符	回到當前循環(huán)的開(kāi)頭,但不測試條件表達式,進(jìn)入下一次迭代。next 和 redo 最大的區別在于next會(huì )進(jìn)入到下一次迭代,而redo則重新執行當前的迭代。帶標簽的塊很少使用,也就是命令一個(gè)循環(huán),以便從內層循環(huán)中直接跳出。LINK: while (<>) {foreach (split) {last LINK if /__END__/;	跳出LINE循環(huán)。...;}}邏輯操作符&&	相當于and||	相當于or它們被稱(chēng)為短路操作符。三元操作符 ?和c的一樣,它就像一個(gè)if-then-else測試。expression ? if_true_expr : if_false_expr一個(gè)利用三元操作符寫(xiě)的多路分支程序my $size =($width < 10) ? "small"   :($width < 20) ? "medium"  :($width < 50) ? "large"   :"extra-large";    缺省值。使用部份計算操作符的控制結構&&,||,?:都有一個(gè)共有的屬性,依賴(lài)于左側值的真假,它們可能計算可不計算一個(gè)表達式,因此叫部份計算(partial-evaluation)操作符。因此它天生就是一種控制結構。第十章 文件句柄和文件測試什么是文件句柄?文件句柄(filehandle)是Perl程序中的一個(gè)名字,表示你的Perl進(jìn)程與外面世界的i/o連接。它是一個(gè)連接的名字,并不是一個(gè)文件的名字。文件句柄的命名方式與其它perl標識符一樣,建議用大寫(xiě)字母。Perl為了自已使用,已經(jīng)有六個(gè)特殊的文件句柄名:STDIN,STDOUT,STDERR,DATA,ARGVAND ARGVOUT。打開(kāi)一個(gè)文件句柄open CONFIG,"test";		打開(kāi)test文件,它所包括的東西通過(guò)名為CONFIG的文件句柄為我們的程序所使用。open CONFIG,"<test";		打開(kāi)test文件,顯式說(shuō)明這個(gè)文件名用于輸入。open CONFIG,">test";		打開(kāi)test文件,顯式說(shuō)明這個(gè)文件名用于輸出。為了輸出打開(kāi)文件句柄CONFIG到新文件test。open CONFIG,">>logtest";	打開(kāi)logtest文件,用于附加。如果文件不存在則生成它。關(guān)閉一個(gè)文件句柄close CONFIG;退出程序時(shí)文件句柄會(huì )自動(dòng)關(guān)閉,但建議最好在完成一個(gè)文件句柄的使用后不久就關(guān)閉它。壞文件句柄系統中會(huì )存在壞文件句柄,如果你試圖向一個(gè)壞文件句柄寫(xiě)入,那么數據會(huì )被無(wú)聲地丟棄。在編寫(xiě)腳本時(shí)用perl -w會(huì )打開(kāi)警告顯示。用die表明致命錯誤unless (open LOG,">>logtest") {die "Cannot create logtest:$!";}或者用另外一種更好的寫(xiě)法open LOG, ">>logtest" or die "Cannot create logtest:$!";	使用or操作符。如果open成功,返回真,or結束,如果open失敗,返回假,or會(huì )繼進(jìn)行到右側代碼。伴隨一條消息死去。你可以用語(yǔ)言去讀它,“打開(kāi)這個(gè)文件,或死去”。$!是系統給出的出錯提示信息,如果die表明的錯誤并非來(lái)自一個(gè)系統請示失敗,請不要包含$!。die "Not enouht arguments.\n" if @ARGV < 2;	命令參數不夠兩個(gè)時(shí),程序退出。使用warn發(fā)出警告信息與die類(lèi)似,但它不退出程序。使用文件句柄一旦打開(kāi)一個(gè)文件句柄,你就可以讀入行。像使用STDIN從標準輸入讀取一樣。例如從unix的passwd文件中讀取行:open PASSWD, "/etc/passwd"or die ”How did yo get loged in?($!)";一個(gè)為寫(xiě)入或附加打開(kāi)的文件句柄可以和print or printf一起使用,緊跟在其后但在參數列表之前:print LOG "filehandle test.\n"		輸出到LOG改變缺省的輸出文件句柄缺省情況下,如果沒(méi)有給print指定一個(gè)文件句柄,輸出就會(huì )發(fā)送到STDOUT,但這個(gè)行為可以用select操作符改變。select LOG;print "this message send to LOG.\n";一旦選擇一個(gè)文件句柄作為缺省的輸出,它會(huì )一直保留,這樣會(huì )把后面的程序搞糊涂,所以要在完成后及時(shí)設回STDOUT。select STDOUT;重新打開(kāi)一個(gè)標準文件句柄如果三個(gè)系統句柄(STDIN,STDOUT,STDERR)的任何一個(gè)不能打開(kāi),Perl會(huì )友好地恢復原來(lái)的那個(gè),也就是說(shuō)perl只有在看到新的連接打開(kāi)成功時(shí)幫把原來(lái)的關(guān)掉。文件測試在perl中有一組完整的測試,你可以用來(lái)了解文件的信息。-e 測試文件是否存在die "ooo!my gods,a file called "$file"already exists.\n" if -e $file;-M 檢查一個(gè)文件是否最新warn "config file is looking pretty old!\n"if -M CONFIG > 28;文件測試和它們的含義-r	文件或目錄對該(有效)用戶(hù)或組可讀-w	文件或目錄對該(有效)用戶(hù)或組可寫(xiě)-x	文件或目錄對該(有效)用戶(hù)或組可執行-o	文件或目錄被該(有效)用戶(hù)或組所有-R	文件或目錄對該實(shí)際用戶(hù)或組可讀-W	文件或目錄對該實(shí)際用戶(hù)或組可寫(xiě)-X	文件或目錄對該實(shí)際用戶(hù)或組可執行-O	文件或目錄被該實(shí)際用戶(hù)或組所有-e	文件或目錄名存在-z	文件存在,大小為零,對目錄總為假-s	文件或目錄存在,大小非零,單位為字節-f	條目是個(gè)普通文件-d	條目的個(gè)目錄-l	條目是個(gè)符號鏈接-S	條目是個(gè)套接字-p	條目是個(gè)命名管道(一個(gè)fifo)-b	條目是個(gè)塊特殊(block-special)文件(如一個(gè)可裝載磁盤(pán))-c	條目是個(gè)字符特殊(character-special)文件(如一個(gè)i/o設備)-u	文件或目錄是setuid-g	文件或目錄是setgid-k	文件或目錄的粘著(zhù)位sticky bit被設置-t	文件句柄是個(gè)TTY(可以由isatty()函數返回,文件名不能由本測試來(lái)測試)-T	文件像個(gè)“文本”文件-B	文件像個(gè)“二進(jìn)制”文件-M	更改年齡(單位為天)-A	訪(fǎng)問(wèn)年齡(單位為天)-C	Inode更改年齡(單位為天)stat和lstat函數stat返回unix的stat系統調用返回的所有信息。它的操作數是一個(gè)文件句柄或是一個(gè)文件名。返回值可能是一個(gè)空列表,表示stat失?。ㄍǔJ俏募淮嬖冢?,或者是一個(gè)13個(gè)元素的數字列表??捎靡韵聵肆孔兞苛斜砻枋龀鰜?lái)。my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) =stat($filename);$dev	文件設置號$ino	文件inode號$mode	文件權限位和一些特別位$nlink	指向文件或目錄的鏈接數$uid	文件的用戶(hù)id$gid	文件的組id$size	文件大?。ㄒ宰止潪閱挝唬?atime	$mtime  $ctime  訪(fǎng)問(wèn),修改,改變時(shí)間$blksize	塊大小$blocks	塊數對符號鏈接使用stat將返回該鏈接所指的東西的信息,而不是符號鏈接本身,除非這個(gè)鏈接碰巧沒(méi)有指向任何目前可以訪(fǎng)問(wèn)的東西。如果你需要(基本上沒(méi)用)符號鏈接本身的信息,就使用lstat。如果操作數不是一個(gè)符號鏈接,lstat則返回與stat一樣的東西。localtime函數把電腦時(shí)間轉換成人可以看得明白的日期時(shí)間。my $timestamp = 19809999393my $date = localtime $timestamp在列表上下文中,localtime返回一個(gè)數字列表。my ($sec,$min,$hour,$day,$mon,$year,$wday,$yday,$isdst) = localtime $timestamp$mon	表示月份,從0-11。$year	表示自1900年起的年數,要加上1900才是真正的年數。按位操作符&	按位與----得到哪些位在兩個(gè)操作數中同時(shí)為真|	按位或----得到哪些位在兩個(gè)操作數中至少有一個(gè)為真^	按位異或----得到哪些位在兩個(gè)操作數中只有一上為真<<	按位左移----把左操作數的位移動(dòng)由右操作數給定的次數,在低位補上0>>	按位右移----把左操作數的位移動(dòng)由右操作數給定的次數,低位會(huì )被丟棄~	按位取反,也被稱(chēng)為一元位補----返回與操作數的每位相反的數使用位串如果一個(gè)按位操作符的任何操作數是一個(gè)字符串,perl就會(huì )進(jìn)行位串操作。也就是說(shuō)"\xAA"| "\x55" 會(huì )得到字符串"\xFF"。使用特殊的下劃線(xiàn)文件句柄_	特殊的文件句柄,使perl用上次文件測試、stat,lstat函數操作后留在內存中的信息。第十二章 目錄操作改變目錄樹(shù)chdir操作符可以改變工作目錄,就像cd命令一樣。chdir "/etc" or dir "cannot cddir to /etc:$!";globshell通常會(huì )把每個(gè)命令中的文件名模式擴展為匹配的文件名,這就稱(chēng)為glod。 如ls *.txtperl中的類(lèi)似的glob操作符。my @all_files = glob "*";	得到當前目錄中的所有文件,不包含以句點(diǎn)開(kāi)頭的文件。my @pm_files = glob ".pm";	得到以.pm結尾的文件。glob的另一種作法在一些老程序中用<>代替glob操作符my @all_files = <*>;目錄句柄目錄句柄(directory handle)和文件句柄在外表和操作上都很像,可以打開(kāi)它(用opendir),讀取它(用readdir),關(guān)閉它(用closedir)。它讀出的是目錄的內容。my $dir_to_process = "/etc";opendir DH,$dir_to_process or die "cannot open $dir:$!";foreach $file (readdir DH) {print "one file in $dir is $file\n";}closedir DH;與文件句柄類(lèi)似,目錄句柄會(huì )在程序結束時(shí)或該目錄句柄在其它目錄上重新打開(kāi)時(shí)被自動(dòng)關(guān)閉。如果我們只想要那些以pm結尾的文件,可以在循環(huán)中使用一個(gè)跳過(guò)函數while ($name =readdir DIR) {next unless $name =~ /\.pm$/;.....}如果要非點(diǎn)文件可以用:next if $name =~ /^\./;如果想要除. 和 ..之外的文件可用: next if $name eq "." or $name eq "..";readdir操作符返回的文件沒(méi)有路徑名部份,僅僅是目錄內的文件名。如passwd,而不是/etc/passwd名字補丁,加上路徑名。opendir SOMEDIR, $dirname or die "cannot open $dirname:$!";while (my $name = readdir SOMEDIR) {next if $name =~ /^\./;		跳過(guò)點(diǎn)文件$name = "$dirname/$name";	補上路徑名next unless -f $name and -r $name 	只要可讀文件.....}遞歸的目錄列表遞歸地訪(fǎng)問(wèn)目錄可用File::Find庫。以進(jìn)行簡(jiǎn)潔的遞歸目錄處理。不用自已寫(xiě)代碼。第十三章   處理文件和目錄刪除文件在perl中用unlink操作符刪除文件,同shell的rm命令一樣。unlink "aa","bb","cc";		把這三個(gè)文件刪除。與glob函數結合起來(lái)可以一次刪除多個(gè)文件unlink glob "*.o";	刪除當前目錄下以.o結尾的文件,與rm *.o相似。unlink的返回值告訴我們有多少文件被成功刪除。my $successful = unlink "aa","bb","cc";print "I delete $successful   file(s) just now.\n";如果想知道那個(gè)文件被刪除,可用循環(huán),一次刪除一個(gè)文件。foreach my $file (qw/aa,bb,cc/) {unlink $file or warn "failed on $file:$!";}一個(gè)很少人知道的有關(guān)unix的事實(shí)。如果你有一個(gè)文件,你對它不能讀,不能寫(xiě),不能執行,甚至文件可能并不屬于你,但你仍然可以刪除它。這是因為unlink一個(gè)文件的權限不依賴(lài)于文件本身的權限位,起作用的其實(shí)是包含這個(gè)文件的目錄的權限位。只要目錄是可寫(xiě)的,就可以刪除該目錄中不屬于自已的文件。在unix中可以通過(guò)設置sticky bit解這個(gè)問(wèn)題,以保護可寫(xiě)目錄。重命名文件rename "old","new";類(lèi)似于mv命令。rename失敗時(shí)返回假,并在$!中設置操作系統的錯誤信息。因此可用or die或or warn顯示給用戶(hù)。一個(gè)把所有以.old結尾的東西rename為以.new結尾的perl程序。foreach my $file (glob "*.old") {my $newfile = $file;$newfile =~ s/\.old$/.new/;	由于.new不是模式,所以點(diǎn)號不用加反斜杠。if (-e $newfile) {warn "can‘t rename $file to $newfile:$newfile exists.\n";} elsif ( rename $file, $newfile) {} else {warn "rename $file to $newfile failed:$!\n";}}鏈接和文件每個(gè)文件都被存在一個(gè)編了號的inode中,每個(gè)inode都包含一個(gè)稱(chēng)為鏈接計數(link count)的數字,當inode沒(méi)有列在任何目錄中時(shí),鏈接計數總是0,也就是空,可以分配給文件。當inode被加到一個(gè)目錄中時(shí),鏈接計數會(huì )遞增;如果此列表項被刪除,鏈接計數會(huì )遞減。目錄包含.,也就是指向自已的inode,所以目錄的鏈接計數應該總是至少為2。文件也可以不止一個(gè)列表項,如鏈接文件。在perl中用link "aa","bb"建立一個(gè)指向aa的鏈接bb。類(lèi)似于在unix shell一執行"ln aa bb"?,F在aa,bb都有相同的inode值,兩個(gè)文件有相同的大小,相同的內容。在aa中加入一行,也會(huì )在bb中加入一行。如果意外刪除了aa,數據并不會(huì )丟失,可以在bb中找回來(lái)。反之也一樣。但如果兩個(gè)文件都刪除了,則數據就會(huì )丟失。目錄列表項中的鏈接規則1、	一個(gè)給定的目錄列表項中的inode號都指向同一個(gè)安裝卷上的inode。這條規則保證,如2、	果物理媒介被移到了另一臺機器上,所有的目錄仍和它們的文件呆在一起。這就是為什3、	么可用rename把文件從一個(gè)目錄移到另一個(gè)目錄的原因,但兩個(gè)目錄必須在同一個(gè)文4、	件系統(安裝卷)中。鏈接不能用于目錄。2、不能給目錄起新的名字。因此目錄不能用于鏈接。以上討論的是硬鏈接,還有一個(gè)符號鏈接,也叫軟鏈接,能繞過(guò)這硬連接的限制。symlink "aa","bb";or warn "cannot symlink aa to bb:$!";這和unix shell 中的"ln -s aa bb" 類(lèi)似。要想知道符號鏈接指向哪里,可以使用readlin函數。如果不是符號鏈接,則返回undef。兩種鏈接都要以用unlink刪除。建立和刪除目錄mkdir函數可以在一個(gè)已有的目錄中建立一個(gè)目錄。返回真時(shí)表示成功。mkdir "aaa",0755 or warn "cannot make aaa directory:$!";第二個(gè)參數是新生成目錄的權限位。以0開(kāi)頭,這個(gè)是一個(gè)八進(jìn)制值。oct函數強制對一個(gè)字符串按八進(jìn)制解釋?zhuān)徽撉懊嬗袥](méi)有0:刪除空目錄,可用rmdir函數。rmdir glob "aa/*";	刪除aa/下所有空目錄。rmdir操作符對非空目錄操作會(huì )失敗。所以要先用unlink刪除文件,再刪除目錄。修改權限perl中有一個(gè)chmod函數,和unix shell中的chmod完成類(lèi)似功能。chmod 0755, "aa","bb";perl中不接受符號權限表達式方式,如+x,go=u-w等。改變所有者chown函數可以改變一組文件的所有者和屬組。chown 1004,100,glob "*.o";可用getpwnam把用戶(hù)名翻譯成一個(gè)數字,用getgrnam函數把組名翻譯成一個(gè)數字。改變時(shí)間戳utime函數可修改文件的訪(fǎng)問(wèn)時(shí)間和修改時(shí)間。my $now = time;my $ago = $now -24*60*60;	每天的秒數utime $now,$ago,glob "*";	把訪(fǎng)問(wèn)時(shí)間設為現在,修改時(shí)間設為一天以前第三個(gè)時(shí)間ctime的值在對文件做任何改變時(shí),總被設為“現在”,因此沒(méi)辦法用utime函數來(lái)設置它。因為在你設置完后它會(huì )立即被重置為“現在”,這是因為它的主要目的就是進(jìn)行增量備份:如果文件的ctime比備份磁帶上的日期要新,就說(shuō)明又需要備份了。使用簡(jiǎn)單的模塊File::Basename模塊	從文件名中抽取基名,取不包括路徑的文件名。通過(guò)use命令聲明一個(gè)模塊use File::Basename;這樣,我們就有了一個(gè)basename函數。my $name = "/usr/local/bin/perl";my $basename = basename $name;	得到perl該函數可用于多平臺,如windows。該模塊中還有一個(gè)dirname函數,它把目錄名從一個(gè)完整文件名中分離出來(lái)。有選擇地使用模塊中的函數當你不需要模塊中的所有函數,或模塊中的函數和你程序中子例程有沖突時(shí),你可以在聲明模塊時(shí)給模塊一個(gè)引入列表,只包括需要的函數。use File::Basename qw /basename/;	只要basename函數,不要其它函數。use File::Basename qw //;		不要任何函數。怎么會(huì )想要一個(gè)空列表呢?這是因為,有引入只是使得我們能使用短的簡(jiǎn)單的函數名,basename,dirname。即使不引入這些名字,我們仍可以使用,只是在沒(méi)有引入時(shí),我們要用全名來(lái)調用它,如:File::Basename::dirname。每個(gè)模塊都有缺省的引入列表,查相關(guān)文檔有介紹。File::Spec模塊用來(lái)處理文件規范(file specification)。它是一個(gè)OO的模塊。用小箭頭而不是::來(lái)引用函數。$newname = File::Spec->catfile($dirname,$basename);第十四章   進(jìn)程管理通過(guò)perl直接啟動(dòng)其它程序。system函數system "date";		啟動(dòng)unix系統的date命令。子進(jìn)程會(huì )運行date命令,它將繼承perl的標準輸入,標準輸出和標準錯誤。system ‘ls -l $HOME‘;	注意是用單引號,因為$HOME是shell變量,否則,shell就看不到美元符號。表明要替換的符號。system "long_time_command&";	把長(cháng)時(shí)間運行的程序放在后臺。system ‘for i in *; do echo ==$1 ==; cat $i; done‘;	可以寫(xiě)腳本避免shell調用system操作符時(shí)帶多個(gè)參數,此時(shí)shell就不會(huì )卷入。如:system "tar","cvf",$aaa,@bbb;	第一個(gè)命令是tar,其余的參數會(huì )一個(gè)一個(gè)傳遞給它。system的退出狀態(tài)基于子進(jìn)程的退出狀態(tài)。在unix中0表示正常,非0表示出錯。unless (system "date") {	返回0表示成功print "we gave you a date,ok!\n";}exec函數與system差不多,system會(huì )生成一個(gè)子進(jìn)程,exec是讓perl進(jìn)程本身去處理所要求的動(dòng)作。一般用system就可以了。環(huán)境變量當你啟動(dòng)一個(gè)新進(jìn)程時(shí),環(huán)境變量就被繼承下來(lái)了。在perl中,通過(guò)特殊的%ENV散列得到環(huán)境變量,散列中每個(gè)鍵表示一個(gè)環(huán)境變量。在你的程序剛開(kāi)始執行時(shí),%ENV就從父進(jìn)程(通常是shell)繼承而來(lái)。修改這個(gè)散列就改變了環(huán)境變量,它又會(huì )被新進(jìn)程繼承。$ENV {‘PATH‘} = "/home/mydir/bin:$ENV{‘PATH‘}";       設置新的環(huán)境變量,增加了一個(gè)路徑delete $ENV{"IFS"};					刪除“IFS”這個(gè)路徑my $make_result = system "make";			在新環(huán)境變量中執行程序使用反引號捕獲輸出當使用system and exec時(shí),所啟動(dòng)命令的輸出都被送到perl的標準輸出上。有時(shí)我們需捕獲這些輸出。my $now = `date`;print "the time is now $now.";		已經(jīng)有換行符,不用加\n。與shell差不多。但它把行尾去掉,而perl的輸出包含\n。所以要得到同樣的效果,需加上chomp操作。在列表上下文中使用反引號my $who_text = `who`;	標量上下文,得到一個(gè)長(cháng)字符串。my @who_lines = `who`;	列表上下文,得到一個(gè)按行分開(kāi)的數據。文件句柄形式進(jìn)程perl可以啟動(dòng)一個(gè)處理活動(dòng)狀態(tài)的子進(jìn)程。啟動(dòng)一個(gè)并發(fā)子進(jìn)程的語(yǔ)法是把命令當做“文件名”用在open調用中,在命令之前或之后加一個(gè)豎線(xiàn),這是一個(gè)“管道”字符,因些,這通常被稱(chēng)為管道打開(kāi)(piped open)。open DATE, "date|" or die "cannot pipe from date:$!";豎線(xiàn)在右邊,其標準輸出與文件句柄DATE連接,就像shell中的date | your_program。open MAIL, "|mail merlyn" or die "cannot pipe to mail:$!";豎線(xiàn)在左邊,命令的標準輸入文件句柄MAIL連接,就像shell中的your_program | mail。命令啟動(dòng)后是個(gè)獨立于perl的進(jìn)程。要讀取一個(gè)為讀而打開(kāi)的文件句柄,我們只需進(jìn)行普通的讀:my $now = <DATE>;要想給郵件進(jìn)程發(fā)送數據,一人簡(jiǎn)單的“帶文件句柄的打印”就可以了:print MAIL "the time is now $now.";用fork進(jìn)行深入和復雜的工作用低級系統調用實(shí)現 system "date";命令。defined (my $pid = fork ) or die "cannot fork:$!";unless ($pid) {exec "date";die "cannot exec date:$!";}waitpid($pdi.0);發(fā)送和接收信號向4201發(fā)送一個(gè)SIGINT。kill 2, 4201 or die "cannot signal 4201 with SIGINT:$!";你也可用“INT”替代這里的2,因為2號信號就是SIGINT。信號0表示,看看我能不能發(fā)一個(gè)個(gè)信號,但我并不想現在發(fā)送。因此可用以進(jìn)程探測。unless (kill 0,$pid) {warn "$pid has gone away!";}第十五章    字符串與排序用index尋找子字符串在大字符串中出現的位置。$where = index($big,$small);例子my $where = index ("howdy world","wor")		where 是 6 .index還有第三個(gè)參數,告訴index從后面某個(gè)指定的位置開(kāi)始搜索,而不是從開(kāi)頭??捎胷index函數找到子字符串最后出現的位置。my $last_slash = rindex ("/etc/passwd","/");	值是4rindex也有可選的第三個(gè)參數,但此時(shí)給出的是允許的最大返回值。用substr處理一個(gè)子字符串substr操作符只作用于一個(gè)大字符串的一部分,它看起來(lái)如下:$part = substr($string,$initial_position,$length);它取三個(gè)參數:字符串值、以零為基準的初始位置(與index的返回值類(lèi)似)和子字符串的長(cháng)度。返回值是一個(gè)子字符串:my $mineral = substr ("hello world",6,5);	得到worldmy $rock = substr "hello world,6,10000";	得到world,第三個(gè)參數可超過(guò)實(shí)現的字符串長(cháng)度。如果想確保到達字符串末尾,不論它多長(cháng)或多短,則只須省略第三個(gè)參數。始初位置可以是負值,意思是從字符串的末尾數起,即-1代表最后一個(gè)字符。index and substr可很好地配合工作。如我們可以取出從字線(xiàn)l位置開(kāi)始的一個(gè)子串:my $long = "a very very long string";my $right = substr($long,index($long,"l"));還可以使用綁定操作符(=~)以限制某個(gè)操作符只作用于字符串的一部份。substr($string,-20) =~ s/aa/bb/g;但在實(shí)現代碼中不會(huì )需要這樣的功能。用substr and index能完成的工作多數也可以用正則表達式完成。不過(guò)substr and index一般會(huì )快一些。四個(gè)參數版本的substr,第四個(gè)參數就是做替換的子字符串。my $previous_value = substr($string,0,5,"Goodbye");用sprintf格式化數據sprintf 和 printf取一樣的參數(除了可選的文件句柄之外),但它返回請求的字符串而不是打印它。my $date_tag = sprintf "%4d/%02d/%02d %2d:%02d",$yr,$mo,$da,$h,$m,$s;在本例中,$date_tag得到的東西類(lèi)似于"2004/01/01 3:00:00"。使用sprintf處理“錢(qián)數”顯示2.50而不是2.5,可用“%.2f”格式完成。my $money = sprintf "%.2f",2.499999";如果你的“錢(qián)數”的太大以至于需要逗號來(lái)顯示它的大小,那么可以用以下例程實(shí)現。sub money {my $number = sprintf "%.2f",shift @_;		每次通過(guò)空循環(huán)時(shí)加一個(gè)逗號1 while $number =~ s/^(-?\d+)(\d\d\d)/$1,$2/;	在合適的地方加上美元符號$number =~ s/^(-?)/$1\$/;$number;第一行格式化第一個(gè)參數以獲得在小數點(diǎn)后準確的兩個(gè)數字。如果參數是數字12345678.9那么我們的$number就是字符串"12345678.90"。下一行使用一個(gè)while修飾符,表示只要替換返回真值(表示成功),循環(huán)體就被執行,但循環(huán)體什么都不做。它可以有兩種其它寫(xiě)法:while ($number =~ s/^(-?\d+)(\d\d\d)/$1,$2/) {1;}和‘keep looping‘ while $number =~ s/^(-?\d+)(\d\d\d)/$1,$2/;這個(gè)替換做了什么呢?模式會(huì )匹配字符串的前面部份,不能匹配小數點(diǎn)后面的部份。記憶$1會(huì )得到"12345",$2會(huì )得到"678",因此替換后會(huì )使得$number變成"12345,678.90"。如果替換成功,則循環(huán)重新開(kāi)始。這次,模式不能匹配逗號以后的部份,因此$number變成"12,345,678.90"。這樣,替換在每次通過(guò)空循環(huán)時(shí)添加一個(gè)逗號。接著(zhù)再進(jìn)入一次循環(huán),但這次模式不能匹配,所以循環(huán)就結束。在字符開(kāi)頭的一個(gè)負號作用是把美元符號放在正確的位置。變樣$number就是"$12,345,678.90"。高級排序內置的sort操作符按ASCII字母順序排序。如果要對組數值,或大小寫(xiě)無(wú)關(guān),或存儲在散列中的信息對一些條目進(jìn)行排序。那就要告訴perl你想要什么樣的順序,方法就是寫(xiě)一個(gè)排序定義子例程。如下一個(gè)數值排序子例程:sub by_number {if ($a < $b ) {-1} elsif ($a > $b) {1} else {0}}如果$a應該$b之前,則返回-1,如果$b應該在$a之前,則返回1,如果$a 和$b的順序無(wú)關(guān)緊要,則返回0,如相等。要使用排序子例程,只須把它的名字放在關(guān)鍵字sort操作符和要排序的列表之間就可以了。my @result = sort by_number @some_number;不需在子例程中聲明$a $b,如果這樣做了,子例程就無(wú)法工作。還有一種更簡(jiǎn)單的寫(xiě)法,而且更有效率。采用<=>操用符。sub by_number { $a <=> $b}cmp是比效字符串的操作符。sub ascii {$a cmp $b)my @stings = sort ascii @any_string;大小寫(xiě)無(wú)關(guān)的比較sub case_insensitive {"\L$a" cmp "\L$b"}	用\L強制把參數變成小寫(xiě)以“內聯(lián)”的方式把排序子例程寫(xiě)進(jìn)代碼中:my @number = sort {$a <=> $b} @some_number;如果按降序排序,可用reverse寫(xiě)成:my @number = reverse sort {$a <=> $b} @some_number;也可以把參數互換達到反序的目的:my @number = sort {$b <=> $a} @some_number;按值排序一個(gè)散列my %score =("aa" => 195,"bb" => 201,"cc" => 40);my @winners = sort by_score keys %score;sub by_score { $score{$b} <=> $score{a} }按照多個(gè)鍵排序如果散列中有兩個(gè)相同的值。那么可以按名字排序。my @winners = sort by_score_and_name keys %score;sub by_score_name { $score{$b} <=> $score{a} 	按數值分數排序or			加一個(gè)低優(yōu)先級的短路or操作符$a cmp $b		按名字根據ASCII字母順序排序}排序子例程不是只能使用兩級排序,允許多級排序。如上例,多加幾個(gè)or操作符就可以了。第十六章	簡(jiǎn)單數據庫DBM文件和DBM散列在每個(gè)有perl的系統都有一個(gè)已經(jīng)可用的簡(jiǎn)單數據庫,以DBM文件的形式存在。這可讓你的程序把數據存儲在一個(gè)文件或一對文件中以便快速查詢(xún)。當使用兩個(gè)文件時(shí),一個(gè)存放數據,一個(gè)存放目錄。有些DBM的實(shí)現對文件中每個(gè)鍵和值的大小有一個(gè)1000字節的限制。但對文件中單個(gè)數據項的數目沒(méi)有限制,只要你有足夠的硬盤(pán)空間。打開(kāi)和關(guān)閉DBM散列要把一個(gè)DBM數據庫和一個(gè)DBM散列關(guān)聯(lián)起來(lái),即打開(kāi)數據庫,可以使用dbmopen函數。dbmopen (%DATA,"my_database",0644)or die "cannot create my_database:$!";第一個(gè)參數是散列的名字,如果這個(gè)散列已經(jīng)有值了,那么在打開(kāi)DBM文件后這些值都將無(wú)法訪(fǎng)問(wèn)。第二個(gè)參數是DBM數據庫名,在硬盤(pán)上通常以一對擴展名為.dir and .pag的文件存儲,但在這里不需要打上擴展名。第三個(gè)參數是權限值。被賦于打開(kāi)的文件。使用大寫(xiě)散列名只是個(gè)傳統,和文件句柄一樣。DBM散列在程序運行的全過(guò)程中一直打開(kāi)。當程序結束時(shí),關(guān)聯(lián)被終止。你也可以用dbmclose關(guān)閉它dbmclose (%DATA)使用DBM散列DBM散列與一般散列幾乎一樣工作??梢栽谏⒘兄刑砑?,刪除,保存數據。只是并非存在內存中,而是在硬盤(pán)上。$DATA("aa") = "test";	生成或更新一個(gè)元素delete $DATA{"aa"};	刪除數據庫中一個(gè)元素while (my($key,$value) = each(%DATA)) {print "$key has value of $value\n";}訪(fǎng)問(wèn)一個(gè)由c程序維護的DBM文件,你就應該知道C程序通常會(huì )在字符的末尾加一個(gè)NUL("\0")字符,原因是c使用NUL字節作為字符串尾標志。DBM庫例程不需要這個(gè)NUL,因此NUL會(huì )被當作數據的一部份被存儲。如果要和C程序合作,就必須在你的鍵和值后面加一個(gè)NUL字符,而把返回值末尾的NUL去掉從而使得數據變得有意義。例如在一個(gè)unix系統上的sendmail別名數據庫中搜索mymail。你可作以下操作:dbmopen(my %ALL,"/etc/mail/aliases",undef) or die "no aliases?";my $value = $ALL{"mymail\0"};		注意附加的NUL$value =~ s/\0$//;			刪去結尾的NULprint "my mail is headed for "$value\n";顯示結果如果你DBM文件被多個(gè)進(jìn)程并發(fā)訪(fǎng)問(wèn),如通過(guò)WEB來(lái)更新,那么就需要一個(gè)附加的鎖文件。具體內容需查詢(xún)相關(guān)資料。在pack and unpack處理數據pack函數取一個(gè)格式字符串和一組參數,然后把參數裝配置到一起構成一個(gè)字符串,unpack還原字符串。my $buffer = pack ("c s l",31,1123,85858);格式c,s,l代表char,short and logn。所以第一個(gè)數字裝入一個(gè)字節,第二個(gè)數字裝入兩個(gè)字節,第三個(gè)數字裝入四個(gè)字節。格式字符可查詢(xún)perlfunc手冊。固定長(cháng)度的隨機訪(fǎng)問(wèn)數據庫固定長(cháng)度不是說(shuō)文件本身,而是指單個(gè)記錄是固定長(cháng)度的,就好像關(guān)系數據庫中的定長(cháng)字段。假如有一組記錄,用pack格式字符代表如下:名字	40個(gè)字符	a40年齡	單字節整數	C分數	5個(gè)雙字節整數	I5日期	4字節整數	L每個(gè)記錄共55個(gè)字節。perl支持使用此類(lèi)磁盤(pán)文件。步驟如下:1、為讀和寫(xiě)打開(kāi)一個(gè)磁盤(pán)文件。用"+<"模式open一個(gè)文件,就對該文件有讀寫(xiě)權限?!?lt;”只是有讀權限?!?>”生成一個(gè)新文件,并對它有讀寫(xiě)權限。2、在這個(gè)文件中移動(dòng)到任意位置。seek函數能在文件中移動(dòng)seek (HEAD,55 * $n,0);第一個(gè)參數是文件句柄。第二個(gè)參數是距文件頭的偏移量,以字節為單位。第三個(gè)參數是0,是“從哪里開(kāi)始”參數,如果你尋址到一個(gè)相對于當前位置的位置,或相對于文件尾的位置,就可使用一個(gè)非0值,多數為0。一旦文件指針用seek定了位,那么下次的輸入輸出操作將會(huì )從那個(gè)位置開(kāi)始。3、按長(cháng)度取出數據,而不是直到下一個(gè)換行符。使用read函數讀取數據。my $buf;	輸入緩沖區變量my $number_read = read(HEAD,$buf,55)讀出55個(gè)字節數據后,可用unpack拆裝它們,以獲得具體信息。my ($name,$age,$score1,$score2,$score3,$score4,$score5,$when) = unpack"a40 C I5 L",$buf;4、按固定長(cháng)度寫(xiě)數據。不是用write,而是用print。并用pack確保長(cháng)度正確。以存入一個(gè)new_score和時(shí)間為例print HEAD pack("a40 C I5 L",$name,$new_scroe,$score1,$score2,$score3,$score4,time);可變長(cháng)(文本)數據庫#!/usr/bin/perl -wuse strictchomp(my $date = `date`);	一個(gè)更好的辦法是使用localtime@ARGV = glob "aa.dat" or die "no files found";$^I = ".bak";		舊文件備份成.bak文件,如果是空串,則不生成備份,但不建議這樣用。while (<>) {s/^aaa:*/aaa:change value/;	修改值s/^bbb:.*\n//;			刪除s/^ccc:.*/ccc:$date/;		更新日期print;}該程序生成一個(gè)修改后的新文件,文件名和舊文件一樣,舊文件被備份成.bak文件。該程序能在幾秒鐘內更新幾百個(gè)文件,功能相當強大。從命令行現場(chǎng)編輯# perl -p -i.bak -w -e ‘s/aaa1/aaa/g‘ bbb*.dat-p	告訴perl為你寫(xiě)一個(gè)程序-i.bak	同$^I設置,生成.bak文件-w	打開(kāi)警告-e	表示后面是可執行代碼最后一個(gè)參數表明@ARGV將包含匹配這個(gè)glob文件名列表。一個(gè)完整的程序如下:#!/usr/bin/perl -w@ARGV = glob "bbb*.dat";$^I=".bak";while (<>) {s/aaa1/aaa/g‘;print;}如果代碼少,只有幾行,采用命令行選項更方便。第十七章	一些高級Perl技術(shù)用eval捕獲錯誤一種捕獲致命錯誤的辦法,把代碼放在eval塊中。eval { $aa = $cc / $dd };	這樣,即使$dd是零,也不會(huì )導程序崩潰。如果出錯,程序會(huì )繼續運行,并不崩潰,$@變量包含了程序崩潰的出錯信息。如果沒(méi)有錯誤,$@為空。它是一個(gè)有用的布爾值。print "an error occurred":$@" if $@;	如果出錯,則打印出錯信息。eval 可嵌套eval不能捕獲的問(wèn)題有四種1、非常嚴重的錯誤,導致perl本身崩潰。2、eval塊中的語(yǔ)法錯會(huì )在編譯時(shí)被抓住,不會(huì )在$@中返回。3、exit操作符立即終止程序。4、警告信息。用grep從一個(gè)列表中選擇條目從一個(gè)大的數字列表中取得奇數條目。my @number = grep {$_ % 2 } 1..1000;這行簡(jiǎn)單的代碼就得到一個(gè)500個(gè)奇數的列表。它是如何工作的呢?grep第一個(gè)參數是一個(gè)塊,其中$_表示列表中每個(gè)條目的占位符,該塊返回一個(gè)布爾值。其余的參數是要搜索的條目列表。grep對列表中的每個(gè)條目計算一次表達式,如果為真就包括到結果列表中。$_不斷地由列表中的一個(gè)元素變成下一個(gè)元素。就好像一個(gè)foreach循環(huán)。grep是perl中的一個(gè)操作符,同unix中的工具名grep同名。能完成相同的工作,但更加強大。下面語(yǔ)句能把文件中提到test的行抓取出來(lái):my @test = grep {/\btest\b/i} <file>;如果你選擇的僅僅是一個(gè)簡(jiǎn)單的表達式,而不是一個(gè)完整的塊,可以不用大括號,用一個(gè)逗號隔開(kāi)就可以了。my @test = grep /\btest\b/i,<file>;用map轉換一個(gè)列表的條目與grep相似,對列表中的每個(gè)條目都計算一次塊,但塊的最后一個(gè)表達式不同,它實(shí)際上成為結果列表的一部份。my @date = (4.22,4,33,5.323,78.2);my @formatted_date = map {&big_money($_)} @date;不加引號的散列鍵如$score {aa},而不必寫(xiě)成$score {"aa"}這類(lèi)不帶引號的簡(jiǎn)單字符串被稱(chēng)為裸字(bareword)。前提是大括號中除了裸字外沒(méi)有其它東西。更強大的正則表達式非貪婪數量符我們在第八章中見(jiàn)到的四個(gè)數量符都是貪婪(greedy)的。意思是它們都盡可能多地進(jìn)行匹配。+?	匹配一次或多次,和加號一樣,但它傾向于匹配盡量少的次數。*?	匹配0次或多次,和*號一樣,但它傾向于匹配最少的次數。在html中去掉所有的<bold>and </bold>標記如果寫(xiě)成:s#<bold>(.*)</bold>#$1#g就不對,因為星號是貪婪的,如果文件中我多個(gè)這樣的標記,它可能匹配第一個(gè)的<bold>和最后一個(gè)的</bold>。{3,10}???	匹配一次或0次。匹配多行文本傳統的正則表達式只能用來(lái)匹配單行文本,perl可以匹配多行文本,用/m匹配內部換行符的位置。切片我們會(huì )碰到只操作一個(gè)給定列表中幾個(gè)元素的情況,例如一個(gè)圖書(shū)館讀者的信息,文件中每行用六個(gè)冒號分隔。但我只需要其中的兩個(gè)信息,這時(shí)我們就可以用切片的方法來(lái)處理:while (<FILE>) {chomp;my @items = split /:/;my($aa,$bb) = ($items[1],$items[5]);....}可以直接寫(xiě)成my $aa = (split /:/)[1];my $bb = (split /:/)[5];也可以更高效和簡(jiǎn)單地寫(xiě)成my ($aa,$bb) = (split /:/)[1,5];切片是從列表中取出幾個(gè)項目最簡(jiǎn)單的方法。數組切片my @numbers =@names [1,2,3,4,9];散列切片my @three_scores = @scores{qw/aa bb cc/};

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
perl基本語(yǔ)法
Perl 語(yǔ)言輸入、輸出怎么寫(xiě)?控制結構如何用?看這一篇就夠了!
Perl 筆記
Perl數字與字符串間的自動(dòng)轉換
Perl 正則表達式 | 菜鳥(niǎo)教程
該學(xué)點(diǎn)編程知識了
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久