第6章:子過程/函數
- 聲明:subfunction_name;
- 定義:subfunction_name {...}
- 函數調用同C:
-
- example_subroutine();或example_subroutine;
- example_subroutine('Perl is', 'my favorite', $language);或example_subroutine 'Perl is', 'my favorite', $language;
- 調用時需保證之前已有聲明/定義
- 傳回值:函數的最後一行代碼可以寫運算式作為傳回值,例如寫$total;也可以使用return語句在函數體中的任意位置返回傳回值
- 函數內部通過@_變數訪問傳入參數:
- Perl中按引用傳參,改變輸入參數將影響函數外的變數
sub log_warning { my $message = shift || "Something's wrong"; my $time = shift || localtime; # Default to now. print "[$time] $message\n"; } |
- 實現參數命名的小技巧:
- 調用:logon(username => $name, password => $pass, host => $hostname);
- 定義:
sub logon { die "Parameters to logon should be even" if @_ % 2; my %args = @_; print "Logging on to host $args{hostname}\n"; ... } |
第7章:Regex
- Regex以雙斜線對//包裹,//中可以使用變數,變數將被代換為對應的值
- 正則式匹配:str =~ /re/若str匹配/re/成功為true,反之false;!~則與=~相反
- /re/等價於$_ =~ /re/
- 進行匹配後,可以使用$1,$2,$3...獲得字串中匹配成功的子串
- 因為不知道有多少個匹配成功的子串,所以需要用defined算符一一檢驗$1, $2, $3是否已定義,stupid
- //正則式中以下元字元(metacharacter)需要使用\轉義:. * ? + [ ( ) { ^ $ | \ /
- \Q可用於關閉元字元,\E用於結束\Q。\Q...\E之間的部分可自由使用上一要點中提到的元字元
- 錨點^表示從字串起始處匹配,而$則表示匹配至字串末尾結束
- []可定義字元集,例如[abc]匹配a,b或c,[0-9]匹配0,1,2,3,4,5,6,7,8,9任一。[]中使用^表達反義,即[^eo]可匹配除e,o外任一字元
- 幾個等價:\d等價於[0-9],\w等價於[0-9A-Za-z_],\s等價於[ \t\n\r\f],\D等價於[^0-9],\W等價於[^0-9A-Za-z_],\S等價於[^ \t\n\r\f],.等價於任一字元(分行符號除外)
- |可用於表示或,例如yes|maybe可匹配yes或maybe,ye(s|t)匹配yes或yet
- ?意味?前面的記號出現0或1次,例如(word )?is可匹配word is和is
- +則為1次及1次以上,*為任意次(包含0次)
- /bea?t/匹配beat和bet
- /bea+t/匹配beat, beaat, beaaat...
- /bea*t/匹配bet, beat, beaat, beaaat...
- {}則可以定義具體的出現次數,例如\s{2,3}可匹配2個空格,也可匹配3個空格。{x}代表x次,{x,}則代表x次及x次以上
- 正則式匹配器的工作原則:
- 一旦匹配無法繼續(下一個字元無法滿足正則式定義),立即停止匹配
- 一旦匹配成功,馬上結束匹配
- 遇+*?三個字元時取最長相符,即匹配至無法匹配時再匹配之後的正則式與字串
- 最近分支原則:若存在分支匹配(例如[a-z]或ye(s|t)這種情況)則從前向後依次嘗試,若嘗試失敗則取下一個,直到成功匹配或所有情況匹配失敗
- 使用正則式進行替換:str =~ s/find/replace/;可用於將str中滿足find模式的首個子串替換為replace,若不指定str,執行s/find/replace/;為對$_操作,在末尾加g修飾符可替換所有子串
$_ = "Awake! Awake! Fear, Fire, Foes! Awake! Fire, Foes! Awake!"; s/Foes/Flee/; print $_,"\n"; 輸出: Awake! Awake! Fear, Fire, Flee! Awake! Fire, Foes! Awake! |
$_ = "there are two major products that come out of Berkeley: LSD and UNIX"; s/(\w+)\s+(\w+)/$2 $1/g; print $_, "?\n"; 輸出: are there major two that products out come Berkeley of: and LSD UNIX? |
- 類似q//和qq//,//和s///也可以使用別的分隔字元,當在匹配(//)中使用其他分隔字元時,需要使用m作為首碼,例如m/^\s*[A-Z]/;m#^\s*[A-Z]#;m{^\s*[A-Z]};等,而s/old text/new text/g;則可以寫為s{old text}{new text}g;也可以出於清晰寫為:
s{old text}
{new text}g;
再如s/\/usr\/local\/share\//\/usr\/share\//g;可寫為s#/usr/local/share/#/usr/share/#g;
- 修飾符
- /m將字串作為多行字串處理,在這種情況下^$不再分別匹配單詞首尾,而是匹配行首行尾
- /s將字串作為單行字串處理,此時.匹配包括分行符號在內的所有字元
- /g:匹配時若有多個可匹配子串則全部匹配;替換時則替換所有可匹配子串,使用此修飾符時可使用\G錨點匹配最後一個可匹配子串的最後一個字元位置
- /x允許以多行方式書寫正則式,且可以添加註釋
- split(re, str)將str按照re分為多個子串,返回包含這些子串的列表。不指定str則預設對$_操作。例如split /:/, “kake:x:10018:10020::/home/kake:/bin/bash”可得(“kake”, “x”, “10018”, “10020”, “”, “/home/kake”, “/bin/bash”)
- join(str, list)可用str將list中各個元素串連為一個字串,並返回這個字串,例如join “#”, (“kake”, “x”, “10018”, “10020”, “”, “/home/kake”, “/bin/bash”)可得“kake:x:10018:10020::/home/kake:/bin/bash”
第8章:檔案與資料
- 開啟檔案:open(filehandle, mode, filename)例如open(FH, '<', 'input.txt')
- 開啟成功時返回true,反之false
- 也可以寫作open(FH, '< input.txt')
- 訪問模式:>寫 <讀 >>追加
- close(filehandle)用於關閉檔案控制代碼,例如close(FH);
- 標量讀入:my $line = <FH>,讀入一行
- 列表讀入:my @list = <FH>,讀入所有行,每行為一個列表元素
- 特殊檔案控制代碼:<>(稱為“鑽石運算子”)
- 當未在命令列參數中指定輸入檔案時,為<STDIN>
- 否則為指定的檔案控制代碼。可指定多個檔案,按指定順序逐個開啟、逐行讀取
- @ARGV為儲存命令列參數的字串數組,例如以perl argv1.pl king crimson rocks運行時@ARGV為(‘king’, ‘crimson’, ‘rocks’)
- <>本質上就是用@ARGV實現的。$ARGV為<>當前檔案控制代碼指向檔案的檔案名稱
- print FH list可以向FH指向的檔案中輸出list
- $|變數設定是否使用OS的輸出緩衝區,預設為0(使用),設為1後不使用
- 管道:將上一個程式的STDOUT輸出接入:open(FH, '-|', command);例如open(FH, '-|', 'perl sort2.pl gettysburg.txt');
- 管道:將當前程式的STDOUT輸出接入下個程式的STDIN:open(SORT, '|-', command);例如open(SORT, '|-', 'perl sort2.pl');
- 管道:可使用IPC::Open2建立雙向管道(未詳述)
- lc(str)將字串str中字母轉換為小寫後輸出,uc(str)則轉換為大寫
- 類似shell的檔案測試:(-operator $file),operator包括:
- e $file存在時為true
- f $file為檔案(不是目錄)時為true
- d $file為目錄時為true
- z $file大小為0時為true
- s $file大小不為0時為true
- r $file可讀時為true
- w $file可寫時為true
- x $file可執行時為true
- o $file為目前使用者擁有時為true
第9章:字串處理
- length(str)返回str的長度
- index(str, substr)返回str中substr第一次出現時的下標,substr不存在時返回-1
- index(str, substr, mindex)指定從mindex開始尋找
- rindex(str, substr)返回str中substr最後一次出現時的下標,不存在時返回-1
- rindex(str, substr, mindex)指定從mindex開始尋找
- substr(string, starting_index, length)返回string中從starting_index開始取length長度的子串
- tr///用於字元替換,例如tr/old/new/將會建立如下字元替換規則:o->n, l->e, d->w,例如$string = ‘2011064’,而執行$string =~ tr/0123456789/abcdefghij/;或$string =~ tr/0-9/a-j/;後,$string變為‘cabbage’
- d修飾符用於刪除字元,例如my $vowels = $string =~ tr/aeiou//;並不能刪除$string中的母音字母,而my $vowels = $string =~ tr/aeiou//d;就可以。再例如$string =~ tr/ //d;可刪除$string中的所有空格
第10章:OS互動
- %ENV儲存了所有環境變數(改變%ENV並不能真正改變系統內容變數設定),例如$ENV{HOME},$ENV{PATH},$ENV{USER}等
- 檔案萬用字元:glob(pattern)函數用以返回下一個滿足pattern的檔案名稱,例如glob(‘*.pl’),等價於<*.pl>,表示所有副檔名為pl的檔案。
while (glob('*.dat')) { print "found a data file: $_\n"; } |
- 可以使用opendir開啟一個目錄,通過readdir函數讀取其中包含的檔案,closedir關閉:
opendir DH, "." or die "Couldn't open the current directory: $!"; while ($_ = readdir(DH)) { … } closedir DH; |
- 以下函數與UNIX API相同或類似,可參照APUE(《UNIX環境進階編程》)
- chdir(directory)
- unlink(list_of_files) 可unlink多個檔案
- rename(old_file_name, new_file_name)
- link(file_to_link_to, link_name)
- symlink(file_to_link_to, sym_link_name)
- readlink(sym_link_name)
- mkdir(directory_name, mode)
- rmdir(directory_name)
- chmod(file_or_directory_name, mode)
- system(command)
- system()函數將執行命令的輸出列印至控制台(STDOUT),返回進程的執行結果(個人推斷:main函數的傳回值)。而使用`command`則可將輸出捕獲,例如:
- $output = `$command`;將$command執行的輸出儲存至字串$output,包括分行符號
- @output = `$command`;將$command執行的輸出儲存至列表@output,每行一個元素,包括分行符號