alenliu's blog
前言
這幾天學習了perl語言,為了在以後看不懂語法時方便快速查詢,寫這篇文章記錄下perl語言關鍵的語法?。我實在沒有興趣去深究這門語言,學習時大部分參考 [link]http://www.runoob.com/perl/perl-tutorial.html 上的教程,本文的大部分內容也是來自這個網站。
perl語法
Perl 基礎語法
- 每條語句以分號
;
結束 - 輸出字串可以使用單引號
'
和雙引號"
,雙引號中的字元會進行轉義輸出,單引號中的字元不會。
print "Hello, world\n"; # 雙引號
print 'Hello, world\n'; # 單引號
輸出結果:
Hello, world
Hello, world\n
- Here 文件,一種定義字串的方法。
$a = 10;
$var = <<"EOF";
這是一個 Here 文件例項,使用雙引號。
可以在這輸如字串和變數。
例如:a = $a
EOF
print "$var\n";
會將<<"EOF"
開始到EOF
之間的所有字元都賦值給變數var
,輸出的var
的值如下:
這是一個 Here 文件例項,使用雙引號。
可以在這輸如字串和變數。
例如:a = 10
Perl 資料型別
標量
標量是Perl語言中最簡單的一種資料型別。這種資料型別的變數可以是數字,字串,浮點數,不作嚴格的區分。在使用時在變數的名字前面加上$
$a = 123; # 數字 123
$b = 1.0; # 浮點數 1.0
$c = "123"; # 字串 123
print "\$a = $a\n";
陣列
陣列是多個標量的順序集合,類似於python中的list
型別。陣列變數以@
字元開頭,索引從0開始。例子如下:
@a = (1, 2, 3); # 整型陣列
@b = qw/hello world/; # 字串資料,第一個元素為字串'hello'
@var_10 = (1..10); # 數字1到10組成的陣列
# 陣列變數通過索引引用
print "\@a[0] = @a[0]\n"; # 輸出數字 1
print "\@b[1] = @b[1]\n"; # 輸出字串 world
print "\@var_10 = @var_10\n"; # 輸出 1 2 3 4 5 6 7 8 9 10
# 獲取陣列大小
$size = @a; # 將陣列變數賦值為標量size,則標量size的值為陣列大小
print "\$size = $size\n"; # 輸出陣列物理大小 3, 而不是元素個數
新增和刪除陣列元素的操作如下:
操作 | 描述 |
---|---|
push @ARRAY, LIST | 將列表中的元素放到陣列末尾。 |
pop @ARRAY | 彈出陣列最後一個元素,並返回它。 |
shift @ARRAY | 彈出陣列第一個元素,並返回它。 |
unshift @ARRAY, LIST | 將列表中的原屬放在陣列前面,並返回新陣列的元素個數。 |
雜湊
雜湊是一個無序的key/value對集合,類似於python中的dict
型別。雜湊變數以%
字元開頭。例子如下:
# 初始化雜湊,以下三種形式都可以
%a = ('a'=>1, 'b'=>2, 'c'=>3); # 推薦的形式
%b = ('a', 1, 'b', 2, 'c', 3);
%c = (-a=>1, -b=>2, -c=>3); # 居然還有這種形式。。無語。。
# 引用雜湊
print "\$a{'a'} = $a{'a'}\n"; # 注意是 $a{'a'},而不是 %a{'a'}!!!
print "\$b{'b'} = $b{'b'}\n";
print "\$c{-c} = $c{-c}\n";
# 提取雜湊的多個值到陣列
@a1 = @a{'a', 'b'}; # 注意是 @a{'a', 'b'},而不是 %a{'a', 'b'}!!!
@keys = keys %a; # 提取雜湊所有的鍵
@values = values %a; # 提取雜湊所有的值
$size = @keys; # 雜湊大小
print "\@a1 = @a1\n";
print "\@values = @values\n";
print "\@keys = @keys\n";
print "\$size = $size\n";
# 新增元素 # 注意是 $a{'d'},而不是 %a{'d'}!!!
$a{'d'} = 4;
# 刪除元素
delete $a{'d'};
看上面的例子,就知道雜湊的語法很怪。。
Perl 條件語句
- if 語句。
- if…else 語句。
- if…elsif…else 語句。
- unless 語句。
- unless…else 語句。
- unless…elsif…else 語句。
unless
語句和if
語句執行條件相反,unless
語句在條件為false時執行。
Perl 迴圈
迴圈語句
- while 迴圈。
- until 迴圈。
- for 迴圈。
- foreach 迴圈。用於迭代一個數組。
@a = (1, 2, 3, 4, 5);
# 列印陣列
foreach $a (@a){
print "$a\n";
}
# 列印陣列
foreach (@a){
print "$_\n"; # $_是一個特殊變數
}
- do…while 迴圈。
迴圈控制語句
- next語句。停止執行從next語句的下一語句開始到迴圈體結束識別符號之間的語句,轉去執行continue語句塊,然後再返回到迴圈體的起始處開始執行下一次迴圈。
$a = 10;
while( $a < 20 ){
if( $a == 15)
{
# 跳出迭代
$a = $a + 1;
next;
}
print "a 的值為: $a\n";
$a = $a + 1;
}
輸出:
a 的值為: 10
a 的值為: 11
a 的值為: 12
a 的值為: 13
a 的值為: 14
a 的值為: 16 # 沒有列印 15
a 的值為: 17
a 的值為: 18
a 的值為: 19
- last 語句。類似C語言的break語句。
- continue 語句。Perl continue 塊通常在條件語句再次判斷前執行。continue 語句可用在 while 和 foreach 迴圈中。
$a = 0;
while($a < 3){
print "a = $a\n";
}continue{
$a = $a + 1;
}
輸出:
a = 0
a = 1
a = 2
- redo 語句。直接轉到迴圈體的第一行開始重複執行本次迴圈,redo語句之後的語句不再執行,continue語句塊也不再執行。
$a = 0;
while($a < 10){
if( $a == 5 ){
$a = $a + 1;
redo;
}
print "a = $a\n";
}continue{
$a = $a + 1;
}
輸出:
a = 0
a = 1
a = 2
a = 3
a = 4
a = 6 # 輸出 6,說明沒有執行continue語句
a = 7
a = 8
a = 9
- goto 語句。類似C語言的goto語句。
Perl 運算子
只列出比較奇怪的地方。。
比較運算子
比較運算子除了如<
符號的形式外還可以是字串的形式。lt
gt
le
ge
eq
ne
cmp
。如:
$a = 1;
$b = 2;
if ($a lt $b) {
print "$a < $b\n";
}
邏輯運算子
支援and
&&
or
||
not
這幾種。and
和&&
都表示邏輯與。or
和||
都表示邏輯或。
引號運算
運算子 | 描述 | 例項 |
---|---|---|
q{ } | 為字串新增單引號 | q{abcd} 結果為 ‘abcd’ |
qq{ } | 為字串新增雙引號 | qq{abcd} 結果為 “abcd” |
qx{ } | 為字串新增反引號 | qx{abcd} 結果為 `abcd` |
其他運算子
運算子 | 描述 | 例項 |
---|---|---|
. |
用於連線兩個字串。 | $a="hello ", $b=“world” , $a.$b 結果為 “hello world” |
x |
將字串重複一定次數。 | (’-’ x 3) 輸出為 —。 |
.. |
範圍運算子。 | (2…5) 輸出結果為 (2, 3, 4, 5) |
-> |
箭號用於指定一個類的方法 | $obj->$a 表示物件 $obj 的 $a 方法。 |
Perl 函式
Perl函式用sub
關鍵字定義,語法如下:
sub fun{
......;
}
直接看一個求平均數函式的例子:
sub average{
my $n = scalar(@_);
my $sum = 0;
foreach my $i (@_){
$sum += $i;
}
return $sum / $n;
}
$average = average(1,2,3,4);
print "\$average = $average\n";
關於函式的幾點說明:
- 傳給函式的所有的引數在函式內部通過一個特殊變數
@_
獲取。scalar(@_)
返回引數的個數。$_[0]
表示第一個引數,$_[1]
表示第二個引數等等。 - 函式中的變數前面都加了
my
關鍵字,是因為預設的變數範圍是全域性的。 - 需要將標量和陣列(或雜湊)同時當作引數傳遞給函式時,需要把陣列(或雜湊)放到最後。
sub test{
my ($a,@b) = @_;
print "$a\n";
print "@b\n";
}
test(1, (2,3,4));
test((2,3,4), 1);
輸出:
1
2 3 4
2
3 4 1
- 函式會根據上下文來返回不同型別的值。
# 標量上下文
my $datestring = localtime( time );
print $datestring;
print "\n";
# 列表上下文
($sec,$min,$hour,$mday,$mon, $year,$wday,$yday,$isdst) = localtime(time);
printf("%d-%d-%d %d:%d:%d",$year+1990,$mon+1,$mday,$hour,$min,$sec);
print "\n";
輸出:
Thu Sep 6 18:59:04 2018
2108-9-6 18:59:4
Perl 引用
引用就是指標,Perl 引用是一個標量型別,它可以指向變數、陣列、雜湊甚至函式,可以應用在程式的任何地方。定義變數的時候,在變數名前面加上\
字元,就得到了這個變數的一個引用。例子如下:
$ref = \$a; # 引用標量
print "$$ref\n";
$ref = \@ARGV; # 引用陣列
print "@$ref\n";
$ref = \%ENV; # 引用雜湊
print "%$ref\n";
$ref = \&average; # 引用函式
print "average = ",&$ref(1,2,3),"\n";
Perl 錯誤處理
當開啟一個檔案失敗時,打印出錯誤資訊並退出程式的例子如下:
$file = '/tmp/123';
# 下面幾種寫法都是等價的
unless (open(DATA, $file)) {
die "Error: $!";
}
die "Error: $!" unless open(DATA, $file);
open(DATA, $file) || die "Error: $!";
open(DATA, $file) or die "Error: $!";
Perl 特殊變數
Perl 正則表示式
Perl 正則表示式的三種形式:
Perl 面向物件
面向物件基礎概念
- 物件:物件是對類中資料項的引用。
- 類:類是個Perl包,其中含提供物件方法的類。
- 方法:方法是個Perl子程式,類名是其第一個引數。
類的定義
一個類只是一個簡單的包(package)。可以把一個包當作一個類用,並且把包裡的函式當作類的方法來用。Perl 的包提供了獨立的名稱空間,不同包的方法與變數名不會衝突。Perl 類的檔案字尾為 .pm
。
直接看一個例子,一個Person類的程式碼如下:
package Person;
sub new
{
my $class = shift;
my $self = {
_firstName => shift,
_lastName => shift,
_age => shift,
};
# 輸出使用者資訊
print "名:$self->{_firstName}\n";
print "姓:$self->{_lastName}\n";
print "年齡:$self->{_age}\n";
bless $self, $class;
return $self;
}
sub setFirstName {
my ( $self, $firstName ) = @_;
$self->{_firstName} = $firstName if defined($firstName);
return $self->{_firstName};
}
sub getFirstName {
my( $self ) = @_;
return $self->{_firstName};
}
1;
使用該類的例子如下:
use Person;
$object = new Person( "小明", "王", 21);
# 呼叫方法獲取姓名
$firstName = $object->getFirstName();
# 呼叫方法更改姓名
$object->setFirstName( "小強" );