1 perl的自動檢測
1.1 命令列的檢測方法
可在程式的第一行的命令列參數中加入-w參數,如下:
#!/usr/local/bin/perl -w
1.2 perl程式內部的檢測方法
在程式中加入如下的行:
use strict;
或
use diagnostics;
2 變數
2.1 標量
一般的使用方法:$scalar。
2.2 數組
一般的使用方法:@array。數組下標從0開始記數。
數組中的元素的類型可以不相同。
數組中元素的使用:$array[1]。
數組的引用(可看作C語言中的指標):$arrayref = /@array;
使用:$$arrayref[1]或@$arrayref。
2.3 雜湊
一般的使用方法:%hash。
雜湊表中元素的使用:$hash{index}。
雜湊的引用(可看作C語言中的指標):$hashref = /%hash;
使用:$$hashref{index}或%$hashref。
雜湊表中內容的輸出方法:
use Data::Dumper;
print Dumper(/%hash);
2.4 變數的類型的確定
可使用函數ref。如:
$arrayref = /@array;
print ref($arrayref);
2.5 變數的範圍
在perl中變數無須聲明,在任何時間、任何地點我們可以隨意地引入變數。但是如果我們沒有在變數前加任何限定的話,那麼不論在哪兒引入的變數都將是全域變數。
為了保持程式的對立性及完整性,perl提供了如下兩種方式實現對變數的範圍的控制。
2.5.1 my範圍
my範圍主要用來聲明局部變數。
my聲明的變數將作用於聲明的層次及同一層次上定義的子程式。
2.5.2 local範圍
local範圍主要用於對全域變數的動態作用。它隻影響聲明的層次以及以內的層次,表明該全域變數在local範圍聲明的層次上進行的值修改只在該層次及以內的層次上有效,而對外層上該全域變數的值不產生影響。
2.6 內部變數
2.6.1
內部檔案控制代碼,接收使用者從鍵盤的輸入。
2.6.2 STDOUT、STDERR
內部檔案控制代碼,STDOUT為標準輸出,STDERR為錯誤輸出。
2.6.3
命令列參數檔案控制代碼。
2.6.4 @ARGV
將命令列參數儲存在數組中。
2.6.5 @INC
將perl搜尋庫的目錄次序儲存在數組中。
2.6.6 %INC
用雜湊結構給出use庫的來源(目錄)。
2.6.7 %SIG
設定perl程式中對訊號的處理常式。如:
$SIG{INT} = ‘IGNORE’;
或
$SIG{INT} = /&hit_control_c;
2.6.8 $_
充當預設變數。當明顯需要一個變數而在語句中未指明時,$_將成為該變數。
一個函數沒有參數且我們知道它必須有一個時。
print;
die if (-f);
看到象Regex的代碼,但沒有包含=~時。
if (m”whatever) { &do_something; }
在foreach迴圈中使用。
foreach (@args) { $_…}
2.6.9 $”
決定將數群組轉換為字串時,perl自動在每個元素之間所加入的資訊。如:
$” = “|”;
print “@arrayName”;
2.6.10 $,
決定將數群組轉換為字串輸出時,perl自動在每個元素之間所加入的資訊,但它只對下面列出的情況下起作用。如:
$, = “|”;
print @arrayName;
2.6.11 $/
決定在print輸出時每一行的末尾所增加的資訊。預設設定為空白。
2.6.12 $/
決定從檔案控制代碼讀取資訊時的資料行的分隔字元。預設設定為’/n’。
2.6.13 $1、$2、$3、…
儲存Regex中由小括弧所指定的匹配部分。
2.6.14 $`、$&、$’
Regex匹配時所匹配前面的文本、實際匹配的文本、匹配之後的文本。
需確認多個匹配時的情況
2.6.15 $0
程式名。
2.6.16 $$
當前進程的ID。
2.6.17 $?
給出任一系統調用或在反記號中給出的命令的最後錯誤狀態。
3 控制結構
注意:在所有控制結構中,即使只有一個語句,也必須加上{ }。
3.1 分支結構
3.1.1 if-else-elsif
文法:
if (condition1)
{
doIfSomething();
}
elsif (condition2)
{
doElsifSomething();
}
else
{
doElseSomething();
}
3.1.2 unless
文法:
unless (condition)
{
doUnlessSomething();
}
3.2 迴圈結構
3.2.1 while
文法:
while (condition)
{
…
}
continue
{
## 每次迴圈結束之後都執行的語句。
}
3.2.2 for
文法:
for (pre_clause; end_condition; clause after each loop)
{
…
}
翻譯成while語句為:
pre_clause;
while (end_condition)
{
…
}
continue
{
clause after each loop;
}
3.2.3 foreach
文法:
foreach 變數 (數組)
{
…
}
3.2.4 until
文法:
until (condition)
{
…
}
翻譯成while語句相當於:
while (!condition) { … }
3.2.5 do … while
文法:
do { clause; } while (condition);
翻譯成while語句相當於:
{clause;}
while (condition) { clause; }
3.2.5.1 do … until
文法:
do { clause; } until (condition);
翻譯成while語句相當於:
{clause;}
while (!condition) { clause; }
3.3 迴圈結構中的控制
3.3.1 next
終止next所指定的標籤處的迴圈的當前一次的執行,開始下一次迴圈,不能跳過continue塊的語句。
文法:
next [標籤];
3.3.2 last
執行last所指定的標籤處的控制結構後面的代碼塊。
文法:
last [標籤];
3.3.3 redo
與next基本相同,區別在於redo不會改變for/foreach的迴圈條件。
4 函數
4.1 函數的調用及傳回值
可用如下方式返回多個值:
sub function {
…
if (condition1) {
return ($value1);
}
…
return (/@array1, $value2);
}
函數的調用方式為:
($return1, $return2) = &function();
或
($return1, $return2) = &function;
或
($return1, $return2) = function();
或
($return1, $return2) = function;
4.2 函數的參數傳遞
函數中的參數傳遞以數組方式進行。
函數定義如下:
sub function {
my ($parameter1, $parameter2, @parameter3)=@_;
…
}
函數的調用方式如下:
&function($value1, $value2, @value3);
函數參數的使用過程中我們需要注意以下一些問題:
l 數組參數的使用
如下的函數定義中可能不能達到我們所要求的效果:
sub function {
my (@array1, @array2) = @_;
…
}
最後我們會發現@array2為空白,傳入的兩個數組被合并到一個數組@array1中了。
l 使用引用方式傳遞
盡量使用引用方式傳遞。對上面的函數我們可用如下方式實現:
sub function {
my ($parameter1, $parameter2) = @_;
my (@array1, @array2);
@array1 = @$parameter1;
@array2 = @$parameter2;
…
}
函數的調用方式為:
&function(/@array1, /@array2);
4.3 動態調用函數
在perl中使用eval來實現函數的動態調用。如:
if (condition1) {
$function = “function1 $parameter1”;
} else {
$function = “otherwise”;
}
eval $function;
…
sub function1 {
my ($parameter1) = @_;
…
}
sub otherwise {
…
}
在eval使用過程中我們應注意以下問題:
l eval中執行的程式完全符合perl的文法;
l eval執行的程式中出錯時不會終止主程式的運行;
l eval能使用主程式中的全部變數。
5 語句的簡潔化
我們可以將if語句:
if (condition1) {
if (condition2) {
clause;
}
}
進行簡潔化:
condition1 && condition2 && clause;
我們可以將unless語句:
unless (condition1) {
unless (condition2) {
clause;
}
}
進行簡潔化:
condition1 || condition2 || clause;
6 Regex
我們用Regex可以完成字串中的模式比對和替換,只能用於標量。
6.1 分界符
Regex可使用/和”作為分界符。具體採用何種分界符可根據匹配模式而定。若匹配模式中出現”,我們可用/作為分界符;若匹配模式中出現/,我們可用”作為分界符。
6.2 萬用字元
6.2.1 正聲明
/D 非數字
/d 數字
/W 非單詞
/w 單詞
/S 非空格
/s 空格
‘.’ 分行符號以外的任一字元
6.2.2 負聲明(只是一個位置,不匹配具體字元)
^ 字串開頭
$ 字串結尾
/b 單詞邊界
/B 非單詞邊界
6.3 多重匹配運算子
6.3.1 貪婪
* 匹配0次,1次或多次
+ 匹配1次或多次
? 匹配0次或1次
{X} 匹配剛好X次
{X,} 匹配X次或更多次
{X,Y} 匹配X到Y次
6.3.2 非貪婪
*? 匹配0次,1次或多次,但匹配可能的最少次數
+? 匹配1次或多次,但匹配可能的最少次數
?? 匹配0次或1次
{X}? 匹配剛好X次
{X,}? 匹配X次或更多次,但匹配可能的最少次數
{X,Y}? 匹配X到Y次,但匹配可能的最少次數
6.4 特殊使用方法
6.5 反向引用
perl支援通過反向引用來從匹配串中取出自己感興趣的內容。對於多個的反向引用,系統按從左至右的順序儲存在系統變數$1、$2、…中。如:
$string = “abcd my content efgh next content ijkl”;
$string =~ /(my c.*ent).*(next c.*ent)/
則第一個括弧中所匹配的內容為my content,儲存在系統變數$1中;第二個括弧中所匹配的內容為next content,儲存在系統變數$2中。
l 嵌套的反向引用
對於嵌套的反向引用,系統對內容的儲存順序可能與具體的perl解釋程式有關,我所測試得出的結論為先從外到內,相同層級的則從左至右。
6.6 修飾符
x 可讀的Regex形式,允許運算式寫成多行
i 大小寫不敏感的Regex
s 將被匹配字串看作單個字串
m 將被匹配字串看作多個字串
o 只編譯Regex一次
g 只對替換方式有用,對被匹配字串中所有能匹配的串進行替換
6.7 舉例