本文转自http://ind.ntou.edu.tw/~dada/cgi/Perlsynx.htm
前言:
這篇文章是花了我很多時間、費了我很多心血才完成的,雖然連我自己都覺得無法達到盡善盡美的境界,但希望能幫助大家入門,稍微了解到Perl到底是個什麼樣的東西,Perl到底有那些強大的功能,那麼這篇文章的目的就達到了。 我分做資料型態、控制敘述、副程式、I/O和檔案處理、Regular Expressions、Spectial Variables、Help 這幾部分來講解,但只是敘述了一些Perl的基本語法而已,Perl活潑的特性和程式的技巧就無法一一詳述了,甚為缺憾。
(1) 資料型態(Data type):
Perl的資料型態大致分為四種:Scalar、Scalar Array、Hash Array、References, 看起來雖少但用起來卻綽綽有餘。尤其在寫Perl程式時可以不必事先宣告變數,這一點對剛學程式語言的人甚為方便, 不過為了以後程式除錯和維護方便,我建議你還是養成事先宣告變數的習慣比較好。
String Operator | Purpose |
x | Returns a string consisting of the string on the left of the operand, repeated the number of times of the right operand. |
. | Concatenates the two strings on both sides of the operator. |
eq | Returns True if the two operands are equivalent, False otherwise. |
ne | Returns True if the two operands are not equal, False otherwise. |
le | Returns True if the operand on the left is stringwise less than the operand on the right of the operator. Returns False otherwise. |
lt | Returns True if the operand on the left is stringwise less than or equal to the operand on the right of the operator. Returns False otherwise. |
ge | Returns True if the operand on the left is stringwise greater than or equal to the operand on the right of the operator. Returns False otherwise. |
gt | Returns True if the operand on the left is stringwise greater than the operand on the right of the operator. Returns False otherwise. |
cmp | Returns -1, 0, or 1 if the left operand is stringwise less than, equal to, or greater than the right operand. |
, | Evaluates the left operand, the evaluates the right operand. It returns the result of the right operand. |
++ | Increments the string by one alphabetic value. |
Value Operator | Purpose |
+ | Computes the additive value of the two operands. |
- | Computes the difference between the two operands. |
* | Computes the multiplication of the two operands. |
/ | Computes the division between the two operands. |
% | Computes the modulus(remainder) of the two operands. |
= = | Returns Ture if the two operands are equivalent, False otherwise. |
!= | Returns Ture if the two operands are not equal, False otherwise. |
<= | Returns Ture if the operand on the left is numerically less than or equal to the operand on the right of the operator. Returns False otherwise. |
=> | Returns Ture if the operand on the left is numerically greater than or equal to the operand on the right of the operator. Returns False otherwise. |
< | Returns Ture if the operand on the left is numerically less than the operand on the right of the operator. Returns False otherwise. |
> | Returns Ture if the operand on the left is numerically greater than the operand on the right of the operator. Returns False otherwise. |
< = > | Returns -1 if the left operand is less than the right, +1 if is it greater than, and 0(False) otherwise. |
&& | Performs a logical AND operation. If the left operand is True m then the right operator is not evaluated. |
|| | Performs a logical OR operation. If the left operand is True m then the right operator is not evaluated. |
& | Returns the valueof the two operators bitwise ANDed. |
| | Returns the valueof the two operators bitwise ORed. |
^ | Returns the valueof the two operators bitwise XORed. |
++ | Increment operator. Increments the variable's value by 1. |
-- | Decrement operator. Decrements the variable's value by 1. |
** | Computes the power of the left-hand value to the power of the rihght-hand value. |
+= | Adds the value of the right-hand operand to the value of the left-hand operand. |
-+ | Subtracts the value of the right-hand operand to the value of the left-hand operand. |
*= | Mlutiplies the value of the left-hand operand to the value of the right-hand operand. |
>> | Shifts the left operand right by the number of bits that is specified by the right operand. |
<< | Shifts the left operand left by the number of bits that is specified by the right operand. |
~ | Performs a 1s complement of the operator. This is a unary operator. |
純量陣列,陣列內的每一個元素都是Scalar variable。宣告及使用方式如下: # 純量陣列以 @ 開頭。
my @array;
my @array=qw(a b c d);
# qw 函數會將其後的每個元素用逗點隔開,效果就像下面這行。
my @array=("a","b","c","d");
# 當然你也可以一個個元素宣告,下面就是存取每一個元素的方法。
# 因為陣列中的每一個元素都是純量變數,所以要以 $ 開頭,
# 剛開始容易搞混,請注意。
$array[0]="a"; $array[1]="b"; $array[2]="c"; $array[3]="d";
# 使用for loop印出陣列內每個元素的值。
for($i=0; $i<=$#array; $i++) {
print "$array[$i]/n";
}
看到$#array這個奇怪的東東沒? 這是Perl的一個特殊用法,代表這個陣列最後一個元素的註標。 由於Perl不必事先宣告變數,也不必預先宣告陣列的大小,甚至可以隨時增加新元素,那我們怎麼知道這個陣列到底有多大呢? 透過這個特殊變數我們可以得知這個這個陣列最後一個元素的註標,自然而然也就知道這個陣列究竟有多大了。 另外Perl只定義了一維陣列的語法,二維以上只能用指標間接來達成。
Perl有上述三個函數可對相關陣列做運算:keys函數可取出相關變數的索引值,組成一純量陣列,注意這些由keys函數取出的索引值沒有次序性;values函數可取出相關變數的元素值;each函數則會取出(索引、元素)對。使用者可視情況而用。
Perl 5新增了參考指標的資料型態,使Perl和C一樣可借由指標建立一些複雜的資料結構。 普通程式是用不到指標這玩意的,下面也只是簡單介紹一下,看不懂的人可不必深究。
$scalarRef=/$scalarVar;
$arrayRef=/@arrayVar;
$hashRef=/%hashVar;
$funcRef=/&funcName;
print $$scalarRef;
print "@$arrayRef";
print $hashRef->{$key};
&$funcRef;
$arrayRef=[[1,2,3,4],a,b,[x,y,z],c];
print "$arrayRef->[0][0]/t$arrayRef->[2]/t$arrayRef->[3][2]/n";
$hashRef={a=>aa,b=>bb,c=>cc};
print "$hashRef->{a}/t$hashRef->{b}/t$hashRef->{c}/n";
(2) 控制敘述(Control Statements)
# Expression 就是條件敘述式,Perl和C一樣沒有定義布林資料型態(Boolean data type),
# 因此 0 是false、非0 是ture。另外要注意字串運算子和數值運算子要分清楚哦。
# Code Segment 就是用大括號括起來的一堆指令,也就是一個Block。
if (Expression) {Code Segment}
if (Expression) {Code Segment} else {Code Segment}
if (Expression) {Code Segment} elsif (Expression) {Code Segment} else {Code Segment}
# elsif 就是 else if
# 如果指令(statement)只有一項,我們可以使用倒裝句法,看起來比較簡潔。
statement if (Expression);
# unless 就是if not
statement unless (Expression);
例:
print "HELLO!/n" if ($name eq "friend");
$x-=10 if ($x == 100);
看吧! C 語言有的Perl大部分都有,學過 C 的人可以毫不費力的學會Perl。
my ($a1,$a2,$a3,...) = @_;
來取出各個參數,當然 my @arg=@_;
或 my %arg=@_;
也是可以的。 由於Perl的語法非常活潑,使得程式在維護時特別棘手,因此寫註解成為一項很重要的工作。 我建議你最好在每個副程式前面加上對這段副程式的描述,特別是需要傳遞的參數要註明清楚。
my $x=3;
,若副程式所用的變數名不小心和主程相同,Perl會以目前正在執行的副程式裡的變數為優先。
close(FILEHANDLE);
Expression | Effect |
open(FH, "<filename") | Opens filename for reading. |
open(FH, "+<filename") | Opens filename for both reading and writing. |
open(FH, ">filename") | Opens filename for writing. |
open(FH, "+>filename") | Opens filename for both reading and writing. |
open(FH, ">>filename") | Appends to filename. |
open(FH, "command|") | Runs the command and pipes its output to the filehandle. |
open(FH, "command|") | Pipes the output along the filehandle to the command. |
open(FH, "-") | Opens STDIN. |
open(FH, ">-") | Opens STDOUT. |
open(FH, "<&=N") | Where N is a number, this performs the equivalent of C's fdopen for reading. |
open(FH, ">&=N") | Where N is a number, this performs the equivalent of C's fdopen for writing. |
例:
# 開啟$filename這個檔案,若開啟失敗則印出die後面的訊息,並結束程式。
open(FILE, $filename) || die "Can't open file $filename : $!/n";
# 下面是一個十分精簡的寫法,和 while($_=<FILE>){print "$_";} 是等效的。
print while(<FILE>);
# 檔案開啟後要記得隨手關閉,這才是寫程式的好習慣。
close(FILE);
# $!和$_都是Perl的特殊變數,下面會介紹的。
這招叫做 here document,XXX可以是你取的任何識別字,XXX
在識別字之間的字都會按照你所寫的樣子輸出,就像<pre>標籤一樣。
而當一行的開頭是XXX你取的這個識別字時,才會停止輸出。
/t tab
/n newline
/r return
/f form feed
/b backspace
/a alarm(bell)
/e escape
/033 octalchar
/x1b hex char
/c[ control char
/l lowercase next char
/u uppercase next char
/L lowercase till /E
/U uppercase till /E
/E end case modification
/Q quoteregexp metacharacters till /E
$x="ls -l";
print "$x"; # Output ls -l
print "/$x"; # Output $x
print '$x'; # Output $x
print `$x`; # Output files in this directory
(5) Regular Expressions
Syntax: $string =~ /regular expression/expression modifier
g | Match globally, i.e. find all occurrences. |
i | Makes the search case-insensitive. |
m | If the string has new-line characters embedded within it, the metacharacters ^ and $ will not work correctly. This modifier tells Perl to treat this line as a multiple line. |
o | Only compile pattern once. |
s | The character . matches any character except a new line. This modifier treats this line as a single line, which allows . to match a new-line character. |
x | Allows white space in the expression. |
/ | Tells Perl to accept the following characters as a regular character; this removes special meanings from any metacharacter. |
^ | Matches the beginning of the string, unless /m is used. |
. | Matches any character except a new line character, unless /s is used. |
$ | Matches the end of the string, unless /m is used. |
| | Expresses alternation. This means the expressions will search for multiple patterns in the same string. |
( ) | Groups expressions to assist in alternation and back referencing. |
[ ] | Looks for a set of characters. |
* | Matchs 0 or more times. |
+ | Matchs 1 or more times. |
? | Matchs 0 or 1 times. |
{n} | Matches exactly n times. |
{n,} | Matches at least n times. |
{n,m} | Matches at least n times but no more than m times. |
/r | Carriage return(CR), ASCII 13(十進位) |
/n | New line, UNIX中代表ASCII 10(十進位), DOS(Windows)系統中則是ASCII 13 + ASCII 10(十進位). |
/t | Tab, ASCII 9(十進位) |
/w | Matches an alphanumeric character. Alphanumeric also includes _. 即 [A-Za-z0-9_]. |
/W | Matches a nonalphanumeric character. 即 [^A-Za-z0-9_]. |
/s | Matches a white space character. This includes space, tab, FormFeed and CR/LF. 即 [/ /t/f/r/n]. |
/S | Matches a non-whote space character. 即 [^/ /t/f/r/n]. |
/d | Matches a digit. 即 [0-9]. |
/D | Matches a nondigit character. 即 [^0-9]. |
/b | Matches a word boundary. |
/B | Matches a nonword boundary. |
/033 | octal char |
/x1B | hex char |
/^abc/
/abc$/
/a|b/
/ab{2,4}c/
/ab*c/
/ab+c/
/a.c/
/[abc]/
//d/
//w/
//s/
/[^abc]/
//*/
/abc/i
/(/d+)/.(/d+)/.(/d+)/.(/d+)/
if ($x =~ /(/d+/./d+)/./d+/./d+/) {
print "海洋大學" if ($1 eq "140.121");
}
m//gimosx
這個Regular Expression相當複雜,主要目的是分析指定的URL,然後取得host名稱、port號碼及對應的檔案。我一項項慢慢解釋:
$url=~m||
m後面跟著的就是分隔符號,| |裡面的就是pattern。
([^/:]+)
match一個字串,裡面沒有/和:字元。找到的字串存在$1中。
:{0,1}(/d*)
match 0或1個:,後面跟著一串數字或nothing。找到的字串存在$2中,若找不到,$2就是空的。
(/S*)$
match一串非空白字元,並以找到的字串為結尾。找到的字串存在$3中。
()=()
($host, $port, $file)=($1, $2, $3)
即$host="my.machine.tw"
$port=8080
$file="/cgi-bin/test.pl"
s/PATTERN/REPLACEMENT/egimox
e | Evaluate the right side as an expression. |
g | Replace globally, i.e. all occurrences. |
i | Do case-insensitive pattern matching. |
m | Treat string as multiple lines. |
o | Only compile pattern once. |
s | Treat string as single line. |
x | Use extended regular expressions. |
例:
$x =~ s//s+//g
把所有的white space全部去除掉
$x =~ s/([^ ]*):*([^ ]*)/$2:$1/
把用":"分開的兩個欄位互相對調
$path =~ s|/usr/bin|/usr/local/bin|
它也可以讓你自訂分隔符號哦
tr/SEARCHLIST/REPLACEMENTLIST/cds
c | Complement the SEARCHLIST. |
d | Delete found but unreplaced characters. |
s | Squash duplicate replaced characters. |
例:
$x =~ tr/this/that/
把"this"替換成"that"
$x =~ tr/a-z/A-Z/
把小寫字母全部替換成大寫字母
$count = $x =~ tr/*/*/
計算$x中有幾個"*"
$_ | The default input and pattern-searching space. |
$digit | Contains the subpattern from a successful parentheses pattern match. |
$. | The current input line number of last filehandle read. |
$! | Contains the current value of errno. |
$0 | The name of the file of the Perl script. |
@ARGV | The command line arguments issued when the script was started. |
@_ | The parameter array for subroutines. |
%ENV | This associative array contains your current environment. |
首先你可以到各大BBS站的WWW板或program板的精華區找找,不過資料不會很多,而且有點雜亂。 再不然你可以到蕃薯藤輸入perl或cgi關鍵字找找,有不少人的homepage上有教人如何用Perl寫CGI程式,還有一堆別人已經寫好的CGI程式可以抓來用用。 說到這裡順便打一下廣告,在http://ind.ntou.edu.tw/documents下有Perl的說明文件,做得相當不錯,不過全是英文的就是了,而我這份講義打好後也會放在IND的homepage上,大家可以抓回去參考參考。
第三種資源就是Perl本身的man pages,你在IND帳號下鍵入 man perl 就可以查閱了,這份文件做得不錯,還根據Perl的各個部分寫了man pages,如Perl syntax, builtin function, regular expression, data structure等, 大家可以用man指令一一查詢,有時候在寫程式時一時忘了某個函數怎麼用,這倒是個方便又快速的查詢方法。我會把這些man pages轉成html格式,放在WWW上讓大家參考。