perl入門

轉載於此
perl是一門免費及開源的腳本語言,由Larry Wall所創造,這門語言以實用,快速開發爲主要目標,與當前流行的面向對象,結構化編程有些格格不入。但是這並不妨礙perl被廣泛流傳和使用,世界範圍內圍繞Perl建立起了非常活躍的社區,很多人在其中不斷幫助完善文檔,創建示例代碼,提供一些第三庫等等。具體可以瀏覽以下兩個網頁:www.cpan.org , www.perl.com.

perl最出名也最擅長的要數文本處理了,很多其它語言要花幾十上百行代碼才能完成的任務,perl可能只需要幾行代碼就能完成。但這些優勢是有代價的,Perl書寫代碼的風格有時常常被詬病,典型的面向過程式語言。還有就是,Perl一直以來所堅持的哲學:只要不引起衝突誤解,代碼可以寫成多種形式–There’s More Than One Way To Do It。這導致Perl在語法上具有非常鬆散隨意的特點,同一件事情常常有多種不同的寫法,有些看起來還很奇特,體現在語法上,Perl的符號特別多,讓Perl在一定程度比較難學易忘。

本文主要簡單介紹一下Perl的基本語法,目的是通過本文,你能基本瞭解Perl的寫法,能夠順利的去讀別人的代碼。天下的語言在一定程度上是相通的,如果有一門語言的基礎,去學另一本語言,入門基本不會太難,但要用到熟,得心應手,第三庫的使用等,這些就需要耐心,假以時日了。

本節主要介紹一下各種數據類型.

(一)語句及註釋:

 Perl語句以分號(;)結尾,用#作爲一行的註釋,沒有其它語言中那種跨行的註釋。

 代碼塊用大括號圍起來,這個和c類似。

 但這個大括號在有些地方是強制要求,如在 if ,for,do, while等語句中。

 它不像其它語言一樣會用縮進來判斷塊。

(二) 變量: 標量(scalar) & 列表(list)

 Perl把簡單的數據類型,如字符串,數字等“單數”的東西統稱爲標量,與之相對的,就是“複數”的東西,如數組。

 標量的聲明都是$開始,如:  $str = "abc"

 多個標量也可以放一處一起聲明:

 ($x, $y, $z) = (11, 22, "no", 4);

 而數組的聲明則是以@開頭,如:@arr = ("abc","edf")

 Perl的變量聲明和很多其它腳本語言一樣,不需要指明類型,直接聲明賦值就可以使用。

 如果只聲明但不賦值,Per會l默認給它賦值爲:undef

 爲了檢查一個變量是否已被賦值,Perl提供了一個操作符:defined 用於判斷一個變量是否已經被賦值。

 if( !defined( $myvar ) ) 

{

   print "uninitialized variable";

}  

(三) 字符串

(1)基本語法

Perl中,所有字符串都是雙引號或單引號括起來的,如: "string"  'string'.

這兩種方式在很多時候相同,不同的是當字符串出現其它變量或轉義符號的時候,雙引號會將變量的內容展開,而單引號的不會。

這和shell script是相似的。

如:

   $var = 234;

   $str1 = "str1:$var";    # 打印出來得到-> str1:234

   $str2 = 'str2:$var';     # 打印出來得到-> str2:$var

(2)拼接

點號(.)用於把字符串進行拼接,這個和其它一些語言直接把字符串連在一起就行不一樣。

要用點號把字符串連起來,如:

$str = “abc”.”efg”; # abcefg

這個用法,和shell script , vim script是一致的。

(3)比較

這裏需要強調的,字符串的比較要用:

lt    小於 
gt   大於 
eq   等於
而不要用== , >=  , <= ,這些符號是用來比較數值類型的。 

(四) 數組

 (1)聲明

 如前所說,數組是一個複數(plaural)形式的變量,它的聲明是以@開頭的,後面跟着小括號放入初始值。

 @arr = (12,34,56);

 同一個數組裏的元素類型不一定要一樣,下面的寫法也是合法的:

 @arr = (12,"abc",'c');

 也可以聲明空數組:

 @arr = ();

 聲明字符串數組時,可以用q,qq,qw系列操作符簡化操作。q代表quoted,  qw代表: quotedword.

 @arr = qq(abc);   # 等價於 ("abc")

 @arr = qw(abc ef gg);   #等價於("abc","ef","gg")

 @arr = q(abc);    #等價於('abc') 

 由上看出qq與qw的區別就在於,qq對將對括號中的整個內容當成一個整體加上雙引號。

 而qw是以空格爲分隔,如上面,對abc, ef, gg分別加上雙引號。

 q與qq相似。

 這幾個操作符的好處在於,當你想在字符串加入轉義符號,引號等符號時,會方便很多。

 qq(\abc)  eq  “\\abc"

 qq("abc") eq ”\"abc\""



(2)數組訪問,插入

 如果想訪問數組裏的元素,就用中括號加下標的方法,和很多其它語言一樣,perl的數組元素從0開始算:

 print $arr[2];

 有人可能注意到了,引用裏面元素的時候,又用了$,而不是@。

 這裏其實有一個原則,用@時,是表示整個數組。

 引用其中的元素時,就用$。

 後面將講到hash類型數組,也是同樣的原則。

 上面是一次訪問一個元素,如果需要取出sub array, 則應如下寫:

 @sub_arr = @arr[1,4];



 Perl中的數組是沒有指定大小的,如果訪問了沒有定義的元素,就會返回undef

 @arr = (1,2,3);

 $ele = $arr[20]; # ele == undef

 如果要往數組中加入新元素,也可以直接用中括號+下標

 $arr[4] = 4; #如果不存在第4個元素就插入,存在就覆蓋。



(3)轉換

 下面提一個很體現 Perl風格的問題,前面說到,用@引用 一個數組時,表示對整個數組的引用,

 但這種引用在不同場合下(context)是表示不同含義的:

 @arr = ("abc", "ed");

 print "arr: @arr" ;

 上面的print會將arr 中的元素一個個的提取出來展開打印,這個好理解。

 但如果我這樣寫呢:

 $sz = @arr;  #

 把數組賦值給一個標量,Perl會把數組的大小賦值給左邊的變量。

 所以上面的例子裏,$sz等於2.

 如果Perl沒法判斷,當前上下文是標量還是數組,默認情況下,@arr都會展開數組裏的:

 @arr2 = (1,2,@arr);  # arr2 == (1,2,"abc","ed").

 但如果這時候,我是想讓@arr當作標量來處理的,怎麼辦?上面的寫法是不行的。

 Perl規定,如果想要指明轉換爲標量類型,就需要加上關鍵字:scalar.

 @arr2 = (1,2,scalar @arr);  # arr2 == (1,2,2)     

(4)sort

    Perl爲數組提供了排序操作符:sort

    默認情況下,sort對數組裏的元素按字母排序,然後返回一個新的數組,舊數組不變。

    @arr = ("abc","rsz","ef");

    @newarr = sort(@arr);

     #  arr = abc rsz ef    newarr = abc ef rsz.

     如果數組裏存的不是字符,或你不想按字符序排序, 可以指定按數字的方式排序。

     sort ({$a <=> $b} @array) 

     大括號表示一個比較函數,<=>是指數值比較,$a $b表示比較的兩個數,這兩個變量是語言預定義的變量不可以更改。

     如果把a,b的順序調換一下,就表示反過來排序。

     如果用了數值排序,而數組中又有字符串元素,那字符串都被當作0,如果有多個字符串,字符串之間仍按字母序來排序。

     如:  @arr = (22,44,33,-12,gg ,hh)

             sort({$a<=>$b @arr);  #   結果:-12 gg hh 22 33 44   

   (5)插入,刪除。 

      Perl提供了push,pop,shift,unshift等函數對數組進行入棧出棧之類的操作。

      push 和 pop作用在尾部,shift 與 unshift作用在頭部。

      @arr = ("ab","bc","ee");

      pop @arr;   # 結果:("ab","bc")

      push(@arr,"hh");  #結果: ("ab","bc","hh")

      shift @arr;   #結果:  ("bc","hh")

      unshift(@arr, "vv"); #結果: ("vv","bc","hh")

(五) hash 數組

 (1) 聲明與初化

  Perl裏的hash數組類似於python裏的dict, c++中的map。

  數組中保存的是<key,value>一對值。

  hash數組用%來聲明。

 %hash = ("key1","value1","key2","value2");

 print "v1:$hash{key1}";  #打印出:value1.

 上面的初始化語句在key,value太多時可讀性很差。

  因此,Perl又提供了另一種寫法。

  %hash = ("key1"=>"value1","key2"=>"value2");

  其中符號 => 與逗號的效果是完全一樣,但這種寫法看起來,就比較容易分辨別哪個是Key,哪個是value.

 (2)插入,刪除與修改

     hash的插入與修改在語法上是完全一樣的。

     $hash{"key"} = "value";

     如果hash數組中原來沒有“key”,就插入,如果有"key"及相應"value",

     如果原來有相應的"key",就修改相應的value爲新的“value".



     Perl提供了一個delete操作符來刪除hash中的元素。

     如: delete $hash{"key"};



  (3)獲取key與value.

      Perl提供了keys 和 values這兩個字來獲取hash中的全部key,value.這兩個人操作符返回的是一個數組。

      如: %hash = ("k1"=>"v1","k2"=>"v2");

             @k = keys (%hash);    #k == ("k1","k2")

             @v = values(%hash);   #v == ("v1","v2")

(六) if / else

 Perl中的if/else語法上和c語言一致,除了要求一定要有大括號。

 邏輯判斷操作: 與(&&), 或(||),非(!) 語法上也很和C是一致的。

 $str = "abc";

 @arr = (2,3,4);

 if( $str && @arr == 3)

    {

    }

  else

    {

     }

  上面的例子是一種比較傳統老式的寫法,前面我說if / else 和C中的語法一致,其實也不大準確。

  Perl自己還提供了一套與C不大一樣的寫法,風格上更像是自然語言一樣。



  $var = 2;

  Print " hello world" if ($var > 0); #注意這行,等價於:   if ($var > 0) { print "hello world";}



  這種寫法就像是自然語言裏的倒序了。

  像上面這種寫法,還有另外一個關鍵字也是同樣適用的: unless

  Print " hello world" unless ($var > 0);

(七) 循環: for / while / foreach

       for ($i=0; $i<100; $i++)

   { 
      print "hello $i \n";
   }



        while( $i < 100 )

         {

               print "hello $i \n";

                $i++;

          }

        上面兩字例子演示了 for / while的寫法,可見是和C 在語法上是一樣的。

        除了for / while ,Perl還提供了一個 foreach 專門用來處理數組。

        @arr = (1,2,3,4,5);

        foreach $item (@arr)

        {

            print "item: $item\n";

       }

       注意foreach 那一行中的小括號是不能省的。

(八) I/O

     Perl中進行I/O操作延用了unix中的IO概念,一切都抽象成文件。

     所以,I/O操作都是對一個文件句柄(file handle)進行操作,包括標準輸入標準輸出。



     (1) 標準輸入,標準輸出。


        前面示例代碼中多次用到了print,在之前的寫法這是標準輸出,但它的功能卻不僅限於標準輸出,事實上它的準確原型是:

        print <file handle> "hello world\n";

        如果省略了 file handle,默認情況下就是標準輸出,標準輸出的句柄 <STDOUT>

        所以前面的print語句,事實上等價於:

        print STDOUT "hello world\n";

        對應的標準輸入是STDIN, 這個兩個變量是Perl預定義的。

        可以看成是一個關鍵字一樣,也不需要在這些變量前面加$,@這類的符號 。

        前面一直只示例了標準輸出,沒有提過標準輸入。

        標準輸入語法上,也很簡潔:

        $line = <STDIN>; #read 

        用尖括號把文件句柄括起來,就相當於從裏面讀數據。



     (2) 文件I/O

         獲取及關閉文件要用Open()/Close()函數。

         $succ=  open(fh,“~/myfile.log”);

          if($succ)

            {

                $line = <fh>;#read one line.

                @all = <fh>;  #read the whole file.

                print "@line \n";

                close(fh);

             }



     值得注意的是,文件句柄的聲明是可以不用加$這種符號,直接寫一個名字就夠了,當然,你如果喜歡加上$,也是沒問題的。

     前面的示例演示了讀入時的最基本的做法,Perl還提供了和C語言裏類似的文件操作函數:seek, tell,

     用來定位到文件的相應位置進行讀寫。

     它們的用法和c語言很相似,具體使用方式,有興趣的讀者可以自己去查閱一下官方文檔。

     前面的open()函數示例了文件打開的最基本形式,事實上,這個函數l還支持設置訪問模式。

     文件訪問模式:

     訪問模式例子說明

     讀(Read)   open(FH,"< FileName");  從文件中讀取

     寫(Write)  open(FH,"> FileName");  向文件中寫入,覆蓋舊文件中的內容

     追加(Append) open(FH,">> FileName");向現有文件的尾部追加數據

     讀寫(Read and Write) open(FH,"+< FileName");讀取和寫入現有文件

     寫入程序 open(PIPEOUT,"| pipeout");  打開程序管道

     讀取程序 open(PIPEIN,"pipein |");  從程序或命令的輸出中取得數據



    如果打開的文件支持寫操作,我們就可以用Print 函數往文件裏寫東西:

    if(open(fh,">~/file.log"))

     {

            print fh "hello file\n";

            close(fh);

     }   
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章