一、簡單變數
===========
1. 整型
$x = 123456;
PERL中將整型資料存放在浮點寄存器中,實際上整型變數在PERL中是當作浮點數來看但,只不過是一種浮點數據的特列。
8進位資料以0打頭
$var1 = 047(十進位39)
16進位資料以0x打頭
$var2 = 0x1f(十進位31)
2. 浮點型
浮點寄存器通常是不能精確的儲存浮點數,會產生誤差。使用浮點數時需要注意指數範圍通常是-309到+308。
e.g.
11.4, -0.3, .3, 3., 64.1e+02, 5.4e04
$value = 9.01e+21 + 0.01 - 9.01e+21; (value為0)
$value = 9.01e+21 - 9.01e+21 + 0.01; (value為0.01)
3. 字串
PELR中字串的結尾沒有C語言中的'/0',需要注意。
PERL中的字串支援單引號和雙引號兩種操作,但是有不同:
雙引號的字串支援簡單的變數替換:
$number = 11;
$text = "This text contains the number $number.";
同時雙引號字串支援逸出字元:
/a Bell
/b Backspace
/cn The CTRL + n character
/e Escape
/E End the effect of /L, /U or /Q
/f Form feed
/l Forces the next letter into lowercase
/L All following letters are lowercase
/n Newline
/r Carriage return
/Q Do not look for specifial pattern characters
/t Tab
/u Force next letter into uppercase
/U All following letters are uppercase
/v Vertical tab
若要在字串包含雙引號或者反斜線,則需要在之前加入一個反斜線作為轉義:
$res = "A quote /" and A backslash //";
單引號與雙引號有2個區別:1.沒有變數替換功能, 2.反斜線不支援逸出字元
在PERL中所有的變數預設都為undef
二、操作符
=====
1. 算術操作符
a)乘冪的基數不能為負:(-5)**2
b)乘冪結果不能超出電腦表示範圍:10**99999
c)取餘運算元如果不是整數,則四捨五入成整數後運算,運算子右邊不能為0
d)單目負可用於變數:-$y(等效$y*-1)
2.整數比較操作符
< 小於
> 大於
== 等於
<= 小於等於
>= 大於等於
!= 不等於
<=> 比較,返回1,0或-1(0兩值相等,1第一個值大,-1第二個值大)
e.g.
$value1 = 20;
$value2 = 30;
print $value1 <=> $value2;
結果為-1
3.字串比較操作符
lt 小於
gt 大於
eq 等於
le 小於等於
ge 大於等於
ne 不等於
cmp 比較,返回1, 0或-1
4. 邏輯操作符
||(or) 邏輯或
&&(and) 邏輯與
!(not) 邏輯非
xor 邏輯異或
5. 位操作符
& 位與
| 位或
~ 位非
^ 位異或
<< 左移位
>> 右移位
PS:若$用於負整數,則PERL會將其轉化成無符號數
6. 賦值操作符
=
+=
-=
*=
/=
%=
**=
&=
|=
^=
7. 自增,自減
8. 字串連接和重複操作符
連接: .(.=)
重複: x
e.g.
$newstring = "potato" . "head";(等於"potatohead")
$newstring = "t" x 5(等於"ttttt")
9.逗號操作符
逗號前的運算式先會被計算
$var1 +=1, $var2 = $var1;
等於:
$var1 += 1;
$var2 = $var1;
$var = 26;
$result = (++$var, $var + 5);(result為32)
10.條件操作符
$result = $var == 0 ? 14 : 7
11. 操作符優先序列
二、列表和陣列變數
================
1. 列表
列表是包含在括弧裡的一序列值,可以是任何數值,也可以為空白。
e.g.
(1, 4.3, "Hello", 55)
()空列表
PS:含有一個數值的列表((4.3))和該數值本身(4.3)是不同的,但是可以轉化
(17, $var, "a string")
(17, 256 << 2)
2. 數組(@)
列表格儲存體在陣列變數中,與簡單變數不同,陣列變數以"@"打頭
@array = (1, 2, 3);
陣列變數建立時初始化值為空白列表(),而且由於PERL用@和$來區分陣列變數和簡單變數,因此可以使用同一個名字表示陣列變數和簡單變數。
e.g.
$var = 1;
@var = (11, 23, $var);
數組儲存
對於數組中的值可以通過下標訪問,第一個元素下標為0。若試圖訪問不在的數組元素時,結果為NULL,但如果給超出數組大小的元素賦值,則數組會自動成長,其中增長的元素填充NULL值。
e.g.
@array = (1, 2, 4, 5);
$scalar = $array[0];
$array[3] = 4; #array is (1, 2, 4, 4)
$scalar = $array[4]; # $scalar is null
$array[6] = 17; # @array is (1, 2, 4, 4, "", "", 17)
數組拷貝
@result = @original
用數組給列表賦值
@list1 = (2, 4, 5);
@list2 = (1, @list1, 65);
對簡單變數賦值
@array = (2, 3, 4);
($var1, $var2, $var3) = @array;
字串中的方括弧和變數替換
"$var[0]" 數組中的第1個元素值
"$var/[0]" 等於"$var"."[0]"
"${var}[0]" 等於"$var"."[0]"
"$/{var}" 等於${var}
列表範圍
(1..10) = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
(3..3) = (3)
(2.1..5.3) = (2.1, 3.1, 4.1, 5.1)
(4.5..1.6) = ()
("aaa".."aad") = ("aaa", "aab", "aac", "aad")
($var1..$var2+4)
數組輸出
print ("@array/n")
數組長度
若陣列變數出現在預期簡單變數出現的地方,則PERL解析為其長度
@array = (1, 2, 4)
$scalar = @array; # $scalar = 3
($scalar) = @array; # $scalar = 1
上面的運算式,實際上把$scalar看成是一個擷取列表元素的運算式了,因此實際上擷取的是列表array的第一個元素的值.
e.g.以數組長度遍曆列表
$count = 1;
while ($count <= @array) {
print ("Element $count: @array[$count - 1]/n");
$count++;
}
子數組
@array = (1, 2, 3, 4, 5);
@subarray = @array[0, 1]; # @subarray=(1, 2)
@subarray2 = @array[1..3]; # @subarray=(2, 3, 4)
@array[0,1] = ("string", 24) #@array = ("string", 24, 3, 4, 5)
@array[1,2] = @array[2,1] 用子數組形式交換兩個元素
數組相關函數
sort - 按字元順序排序
@array = ("this", "is", "a", "test");
@array2 = sort(@array); # @array2=("a", "is", "test", "this")
reverse - 反轉數組
@array2 = reverse(@array);
chop - 數組去尾
去掉STDIN輸入字串時最後一個字元-分行符號,若用到數組上,則對數組的每一個元素都進行去尾處理。
@list = ("rabbit", "12345", "quartz");
chop (@list); # @list = ("rabbi", "1234", "quart")
join/split - 串連/拆分
join的第一個參數是串連所用的分割符,其餘為待串連的字元數組
$string = join(" ", "this", "is", "a", "string"); # "this is a string"
$string = "words::and::clons"
@array = split(/::/, $string); # @array=("words", "and", "colons");
三、檔案讀寫
===========
1. 開啟、關閉檔案
open (filevar, filename)
filevar: 檔案控制代碼
filename: 檔案名稱
PERL中有三種訪問模式:讀、寫、添加。寫入模式會將原有資料覆蓋,而添加模式,是在檔案末尾加入新內容。但是不能對檔案進行讀寫/添加操作
open(MYFILE, "myfile") 讀
open(MYFILE, ">myfile") 寫
open(MYFILE, ">>myfile") 添加
檔案開啟處理:
if (open(MYFILE, "myfile)) {
# here's what to do if the file opened succesfully
}
unless(open(MYFILE, "myfile")) {
die ("Can not open input file!/n");
}
open(MYFILE, "myfile") || die ("Could not open file.");
使用完畢後需要用close(MYFILE)關閉檔案
讀檔案操作
$line = <MYFILE> 從檔案中讀取一行資料到變數$line中,並且把檔案指標向後移動一行。對於<STDIN>不需要開啟檔案,即可操作
@array = <MYFILE> 把檔案全部內容讀入數組@array,檔案每一行(包含斷行符號)為@array的一個元素。
寫檔案
open(OUTFILE, ">outfile")
print OUTFILE ("Here is an output line./n")
PS: STDOUT, STDERR為標準輸出和標準錯誤檔案,通常為終端,因此不需要開啟檔案
處理檔案狀態
-op expr
e.g.
if (-e "path/file1") {
print STDERR ("File exists./n");
}
-b 是否為塊裝置
-c 是否為字元裝置
-d 是否為目錄
-e 是否存在
-f 是否為普通檔案
-g 是否設定了setgid位
-k 是否設定了sticky位
-l 是否為符號串連
-o 是否擁有該檔案
-p 是否為管道
-r 是否可讀
-s 是否非空
-u 是否設定了setuid位
-t 是否表示終端
-w 是否可寫
-x 是否可執行
-z 是否為空白檔案
-A 距上次訪問多長時間
-B 是否為二進位檔案
-C 距上次訪問檔案的inode多長時間
-M 距上次修改多長時間
-O 是否只有真正使用者所有
-R 是否只有真正使用者可讀
-S 是否為SOCKET
-T 是否為文字檔
-W 是否只有真正使用者可寫
-X 是否只有真正使用者可訪問
命令列參數
@ARGV是PERL中的命令列參數數組,但是@ARGV[0]並不是代表檔案名稱,而是第一個參數。
$var = $ARGV[0]; #第一個參數
$number = @ARGV; #參數個數
PERL中<>操作符,實際上是對數組@ARGV的隱含引用:
1. 當PERL解析器第一次看到<>時,開啟以$ARGV[0]為檔案名稱的檔案
2. 執行動作shift(@ARGV); 把數組@ARGV的元素向前移動一個,其元素量減少1
3. <>操作符讀取在第一步開啟的檔案中的所有行
4. 讀完後,解析器回到第一步重複
e.g.
@ARGV = ("myfile1", "myfile2"); #實際上是由命令列參數賦值
while ($line = <>) {
print ($line);
}
把檔案myfile1和myfile2的內容打出來。
開啟管道
open (MESSAGE, "| cat > hello")
等價於
open (MYPIPE, ">hello")
四、模式比對
===========
五、控制結構
===========
1)條件判斷
if (<expression>) {
<statement_block_1>
} elseif (<expression>) {
<statement_block)2>
}
...
else {
<statement_block_n>
}
2)迴圈
a)while迴圈
while (<expression>) {
<statement_block>
}
b)until迴圈
until(<expression>) {
<statement_block>
}
c)for迴圈
for ($count = 1; $count <= 5; $count++) {
# statements inside the loop go here
}
d)foreach迴圈
foreach localvar (listexpr) {
statement_block;
}
e.g.
foreach $word (@words) {
if ($word eq "the") {
print ("found the word 'the'/n");
}
}
e)do迴圈
do {
statement_block
} while/until(condexpr)
f) 迴圈控制
退出迴圈last(C的break)
執行下一個迴圈next(C的continue)
redo重複此次迴圈,迴圈變數不變,但是redo在do迴圈中不起作用。
g)goto
goto label;
3)單行條件陳述式
statement keyword condexpr
其中keyword:if, unless, while, until
e.g.
pirnt ("This is zero./n") if ($var = 0);
print ("This is zero./n") unless ($var != 0);
PS:雖然條件判斷在後面,但是是先行執行。
六、子程式
=========
1. 定義
sub subroutine{
statements;
}
2. 調用(&)
&subname;
...
sub subname {
...
}
3. 先定義後使用可以省略&符號
sub subname {
...
}
subname;
4. 向前引用,現定義字程式名,後定義子程式體
sub subname;
...
subname;
...
sub subname {
...
}
5. 用do調用
do my_sub(1, 2, 3);#等價&my_sub(1, 2, 3);
6. 傳回值
預設情況,子程式最後一個語句作為傳回值
7. 局部變數
my 定義的變數只在該子程式中存在
local定義的變數不存在於主程式中,但是存在在該子程式和該自春光許調用的子程式中
e.g.
my ($scalar) = 43;
local(@array) = (1,2,3);
8. 參數傳遞
&sub1($number1, &number2, &number3);
...
sub sub1{
my($number1, $number2, $number3) = @_;
...
}
9. 傳送數組
&addlist (&mylist);
&addlist ("14", "6", "11");
sub addlist {
my (@list) = @_;
...
}
當參數為數組的時候,子程式只能將其賦給一個陣列變數
10. 別名傳遞數組參數(引用傳遞)
@myarray = (1, 2, 4, 5);
&my_sub(*myarray);
sub my_sub {
my (*subarray) = @_;
}
在定義數組別名後,如果有相同的簡單變數,則對該簡單變數的操作同樣會影響到別名數組。
11. 預定義子程式
PERL5中預定義了三個子程式:
BEGIN子程式在程式啟動時候調用
END子程式在程式結束時被調用
AUTOLOAD在找不到某個子程式時被調用
e.g.
BEGIN {
print ("Hi! welcome./n");
}
AUTOLOAD {
print ("HHH/n");
}
若預定義子程式定義了多個,BEGIN按順序執行,END按逆序執行。
七、關聯陣列
八、格式化輸出
九、檔案系統
十、引用(指標)
=============
PERL5中有兩種類型的參考型別:硬引用和符號引用。符號引用包含變數的名字,它對於運行時建立變數名,並定位很有用處。基本上,符號引用就像檔案名稱或UNIX系統中的軟串連。而硬引用則像檔案系統中的硬串連。
硬引用跟蹤引用計數器,當其數為0時,PERL自動將被引用的資料釋放,如果該資料是對象,則析構釋放到記憶體池中。對於非簡單變數的引用必須顯示的解除引用,並且告訴其應當如何做。
1)使用引用
任何簡單變數均可儲存硬引用,因為數組和哈西表含有多個簡單變數,所以可以建立多種組合而成的複雜的資料結構,如數組的數組,哈西表的數組。
取地址:
如果$pointer的值為一個數組的指標,則@$pointer可以訪問數組中的元素,表示取出$pointer中的地址值當作數組使用。類似%$pointer表示指向哈西表中的第一個元素的引用。
建立使用引用
反斜線(/)與C語言中傳遞地址操作符類似(&),PERL中用'/'符號建立一個新的引用:
$variavle = 22;
$pointer = /$variable;
$ice = "jello";
$iceptr = /$ice;
引用$pointer指向$variavle的值位置,引用$iceptr指向"jello",即使$varivle銷毀,仍然可以使用$pointer訪問該值,這是一個硬引用,所以必須同時銷毀$pointer和$variavle以便釋放空間。
例子中引用變數$pointer儲存的是$variavle的地址,而不是值本身,若要擷取的其值,則用兩個$$符號
e.g.
$value = 10;
$pointer = /$value;
printf "$$pointer";
2) 引用和數組
$pointer = /@ARGV
$i = 0;
foreach (@$pointer) {
print "$i: $$pointer[$i++]/n";
}
通過引用訪問哈西表的形式為$$pointer{$index}($index為哈西表索引值),構造哈西表還可以用=>符號:
%weekday = {
'01' => 'Mon',
'02' => 'Tue',
...
};
使用哈西表和數組時,用$和用->是等效的:
$$name[0] = "kamran";
等效於
$name->[0] = "kamran";
$$lastnames{"kamran"} = "Husain";
等效於
$lastnames->{"kamran"} = "Husain";
3) 子程式的引用
$pointer_to_sub = sub {... declaration of sub ...};
調用函數指標
&$pointer_to_sub(parameters);
4)檔案控制代碼的引用
/*FILEHANDLE
e.g.
splitOut(/*STDIN);
splitOut(/*LPHANDLE);
十一、物件導向
十二、包和模組