Perl語言簡介

什麼是Perl?  
Perl是一個能用來完成大量不同任務的編程語言。可以用來解開一個文件並打印一份報告,或者將一個文本文件轉換成另一種格式。Perl爲相當複雜的問題提供了一系列的工具,包括系統編程。  

用Perl寫的程序叫腳本(Perl scripts),而perl程序(perl program)通常是指名字叫做perl的程序,它是用來執行腳本的。  

Perl是解釋型(不是編譯型)語言。這樣,運行一個腳本,和運行一個相應的C程序來講,要花費相當多的CPU時間。但是,現在的計算機速度越來越快,寫一個C程序花的時間比寫一個Perl腳本多,從而總的來講,反而節省了你的時間。  

Hello world!  
我們還是來寫一個Hello world腳本。通過它來介紹Perl腳本的編寫和運行的一些最基本的東西。  

現在開始:  

[Jobs /]cat >;hello  
#!/usr/bin/perl  
print "Hello world!/n";  
[Jobs /]chmod a+x hello  
[Jobs /]./hello  
Hello world!  
[Jobs /]  

註解:  

1. 用cat命令創建一個叫hello的文件,它包含一個很簡單的Perl腳本。通常可以用別的編輯器來創建腳本。  
2. 第一行腳本是, #!/usr/bin/perl。它表示腳本是由perl程序來運行的。它是一個必須的前綴。/usr/bin/perl部分是perl程序的路徑名。不同的安裝,路徑名是不同的。  
3. 隨後是相應的Perl腳本,這裏僅有一行。這一行是很好理解的,其中/n代表newline(換行)。在Perl的字符串,控制字符通常使用這種與C語言類似的表達法,/後跟一個字符。  
4. 程序寫完之後,用chmod命令讓這個包含腳本的程序可以執行。在Linux裏,文件創建是通常是不可執行的,必須明確的改變文件的屬性。在這個命令中all用戶能execute(執行)這個文件。  
5. 最後,鍵入腳本文件名就能運行這個腳本了。 ./表示是在Jobs目錄下的那個文件。  

注意,在Perl中,和C語言一樣,一個語句是一個分號結尾的。  

數據結構和變量  
在Perl中一個變量的值可以是一個數字或字符串或其它別的東西。變量是沒有類型的。你可以將一個字符串賦給一個變量,以後,你可以將一個數字賦給同一個變量。  

變量在使用前不需要申明。  

試圖使用一個沒有初始化的變量,你用的實際上是0或者一個空的字符串或真假值中的false(假),具體是哪個值,由上下文決定。在使用命令行開關時,表示要求Perl解釋器能給出告警信息,比如,-w報告使用了沒有定義的值。  

Perl has three data structures:  

Perl有三種數據結構:scalars,scalars數組,scalars聯合數組,就是"hashes"。  

Scalar變量名通常以$符號開始,如$myvar。  

數組通常以@符號開始,如@myarray。  

Hashes的名字通常以%開始,如%myhash。  

另外,子程序的名字以&開始,通常這個&可以省略。  

上面的符號可以和英語中的單詞相對應:  
$ 和 the,  
@ 和 these or those,  
% 和 these or those,  
& 和 do。  

名字是區分字母的大小寫的。比如$foo和$Foo是兩個不同的變量。  

如果有個數組,如@myarr,你可以用方括號來索引它的某個成員。但此時@要變成$,如$myarr[5]。因爲這個成員是一個scalar變量。  

也可以組成一個數組,如@myvar[5..10],它是一個數組,是由@myvar組成的,它們的索引分別在5和10之間。  

數組的索引是整數,從0開始,和C語言一樣。  

Hashes,能用字符串來索引它的成員,因此,索引方法不同。對於hashes,索引用大括號表示,如$myhash{'foobar'}。同樣,被索引的成員是scalar,必須用$開始。  

每種變量都有他們自己的名字空間。因此$foo和@foo是不同的變量名。同樣$foo[1]是@foo的一部分,而不是$foo的一部分。另外,有兩個預定義的變量,$_和@_。必須知道$_[2]是@_中的一個成員。  

一個數組事實上是一個值的列表。在Perl中,可以用以下方法來生成一個列表,  
(2, 3, 7, 42)  

一個列表可以賦給一個數組變量,如  
@foo = (2, 3, 7, 42);  

列表在Perl中是很重要的,因爲許多操作的結果是列表。  

例子:顯示的行帶行號  
下面的例子顯示scalar變量的使用。同時也介紹了Perl的幾個基本特徵。  

這個腳本打印出它的輸入,但輸出的每行有一個行號開始:  

#!/usr/bin/perl  
$line = 1;  
while (<>;) {  
print $line, " ", $_;  
$line = $line + 1; }  

Scalar變量$line是行記數。在一開始,它被初始化爲1,在每次處理一行的循環中它的值加上一個1。  

循環結構的形式如下:  
while (<>;) {  
處理一行輸入 }  

儘管看上去有點神祕,它確實非常便於使用。你不必關心真正的輸入操作;就用上面的結構就可以了,用預定義的變量$_來引用輸入行。  

print語句包含三個參數,一個是打印行號,一個是打印一個空格,另一個是打印整個的輸入行。沒有打印換行,因爲變量$_中已經包含了換行符了。  

實際上,可以將代碼寫的更加簡潔:  

#!/usr/bin/perl  
$line = 1;  
while (<>;) {  
print $line++, " ", $_; }  

這裏,語句中包含了$line++ 而不僅僅是$line, 因爲在Perl中,和C語言類似,你可以通過給變量加一個運算符來表示對一個變量加1操作。  

如果希望行號是右對齊的,比如行號顯示在固定的5個字符這樣的區域內,左邊的用空格來填充。這相當簡單,只需用下面這條語句代替print語句:  
printf "%5d %s", $line++, $_;  

Perl腳本的輸入  
Perl腳本從那裏得到輸入值?默認的,即在輸入沒有任何參數的情況下,輸入來自Linux中所謂的輸入流。通常是用戶的鍵盤。  

通常希望腳本從文件中輸入。簡單的將文件名作爲命令行參數,也就是,腳本文件的名字是命令的時候。這樣,舉個例子,如果你已經寫好了這個簡單的腳本,並命名爲lines,你可以用下面的方法來測試:  

[Jobs /]./lines lines  
1 #!/usr/bin/perl  
2 $line = 1;  
3 while (<>;) {  
4 print $line++, " ", $_; }  
[Jobs /]  

你可能寫了幾個文件名字作爲命令行參數,比如:  
lines foo bar zap  

這意味着腳本lines將文件foo, bar, 和 zap 作爲一個已經合併的單個文件來處理。  

例子:拆分輸入行  
在Perl中,你可以不用詳細地寫代碼就能將數據分成幾個域。只需指定你想做什麼。  

比如,語句:  
split;  

首先將當前輸入行分解成有空格分隔的域,然後將這些域分別賦值給預定義數組@_。隨後,就可以使用索引來存取這些域。變量$#_ 包含域的數目:它的值是域的數目減1。  

假設,舉個例子,有一些數據,每行包括幾個由空格分隔的項,如果寫一個Perl腳本,將每行的第二項挑選出來。可以寫下面這樣的一個腳本來實現。  

#!/usr/bin/perl  
while (<>;) {  
split;  
print $_[1], "/n"; }  

要注意的是由於在Perl中索引值從0開始,因此用一個值爲1的索引是引用第二個域。  

控制結構  
Perl有豐富的控制結構。理論上,通常也很實際,可以用if語句來實現分支結構,while語句來實現循環結構。  

在控制結構中,實現有條件執行的動作,或循環執行的動作做爲blocks。一個塊是一個有大括號圍起來的一系列語句。注意,括號是必須的,這和C語言略有不同。  

最簡單的if語句的格式是:  
if(expression)block  

它表示,先計算表達式的值,如果表達式的結果爲真的話,就執行塊語句。  

比如,語句if($i < 10) {$j = 100;} ,如果$i的值小於10的話,$j的值就設爲100。  

一個有兩個分支的語句的格式如下:  
if(expression)block1 else block2  

首先計算表達式的值,如果爲真,執行block1,否則執行block2 。  

while語句的格式如下:  
while(expression)block  

先計算表達式的值,如果爲真,執行塊裏面的語句,然後,再計算表達式的值,直到表達式的值爲假,否則,還要執行塊裏的語句。  

下面的腳本是一個使用while語句的簡單例子,它將輸入行進行分解,按相反的方向把各個域打印出來。  

#!/usr/bin/perl  
while (<>;) {  
split;  
$i = $#_;  
while($i >;= 0) {  
print $_[$i--], " "; }  
print "/n";  
}  

在內部的while循環,控制是建立在使用一個輔助的變量$i上的。它的值初始化成對最後一個域的引用,並且不斷遞減,直到爲0,此時,所有的域都處理完畢。運算符>;=的意思是大於或等於。  

字符串處理  
Perl有強大的字符串處理工具。比如,通常希望將輸入數據轉換成小寫,很簡單:  
tr /A-Z/a-z/;  

這可以理解成:將範圍是A到Z的所有字符轉換(translate)成範圍是a到z的字符。  

這個操作是在變量$_上,也就是當前輸入行上進行的。如果你想將它用到變量$foo上,你必須這樣寫:  
$foo =~ tr /A-Z/a-z/;  

有可能這樣的表達式很怪,但一旦熟悉之後,Perl的字符串工具很容易使用。  

例子:文件重命名  
Linux用戶需要將以後綴,比如.for結尾的文件的名字都重新命名成另一個後綴,比如.f。通常沒有直接的命令來完成這一個任務。如果你想要用mv *.for *.f ,通常這樣並不能解決問題。  

但可以用Perl來寫一個簡單的腳本來實現:  

#!/usr/bin/perl  
while(<*.for>;) {  
$oldname = $_;  
s//.for$//.f/;  
rename $oldname, $_;  
}  

while語句表示它只對*.for的名字進行處理。首先將找到的要處理的文件名,把匹配的文件名賦給$_變量。  

在循環體內,首先將$_變量所指的文件名保存到變量$oldname 裏。隨後,對它進行替換。  

最後,用替換好的名字來重命名文件。rename是Perl的一個內建函數,他有兩個參數。我們可以用另一條語句來代替它:  
system "mv $oldname $_";  

它是通過調用操作系統命令來實現的。  

另外,需要注意的是語句s//.for$//.f/;中的兩個/。如果該語句中沒有/,則成爲:  
s/.for$/.f/;  

這個語句就不對了。如果遇到zapfor.for ,就會產生如下替換:za.f.for。因爲符號.代表任意字符。所以.for的意思是只要在字符串中包含for,就做替換。因此會產生上述結果。爲了表示.,就必須用到換碼序列,用/.來表示符號.。這與C語言中的概念類似。  

小結  
Perl語言的語法和C語言有些相同之處,比如控制結構,語句的;結尾,換碼序列等等。但它們也有明顯差別。C語言是編譯型的,C程序的運行效率高。Perl語言是解釋型的,腳本的運行效率比較低。但是Perl語言的綜合性較高,編寫一些功能較複雜的程序所化的時間比較短。另外,Perl的變量是沒有數據類型。  

參考資料  
1、MU Campus Computing的Introduction to Perl or, Learn Perl in Two Hours 。  

2、The Perl Language Home Page 包括一些有關Perl的有用的信息,如Perl FAQ。  

3、在Windows 95和NT上使用Perl語言。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章