1. 程式人生 > >alenliu's blog

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( "小強" );