perl 入門指引
題記:把這篇文章發(fā)到c++專區(qū),沒有嘩眾取寵的意思,這里我想套用阿里巴巴一個資深CTO的話:程序員的知識結構應該是T形的,要精通一到兩門編程語言作為主干,而在頂端則是要多種語言結合使用,也就是我們常說的深度和廣度,那么為什么要學習Perl,我相信有過Perl經驗的程序員一定會對這種腳本語言語義的豐富和強大的字符處理能力有深刻的印象。的確,對于習慣了靜態(tài)語言的我們,Perl是個全新的世界,沒有變量聲明,沒有main函數,比起c++, 我覺得perl更向是一個不羈的頑童,perl的語法中充滿了freedom的思想
假設有以下一個任務,編一個函數將一個文件中所有在尖括號中間的字符由小寫轉換為大寫,這個工作如果用c++來完成的話可能得費一番心思,來看看Perl的解決方案吧
以上是perl的解決方案,第一句話是perl的調用語句,對于windows系統(tǒng)意義不大,第二句話是將讀入的第一個參數傳入子例程replaceString,數組ARGV用來存放命令行傳入的參數,接下來就是子例程,其中的核心語句就是s/\w*(<[^>]+>)/\U$1/g;向天書一樣,不過如果你對正則表達式熟悉的,也可以看出一些門道來,這也正是perl語言的強大之處,對于正則表達式的原生支持
學習perl,首先要忘掉C++古板的作風:
1,這里沒有main函數,perl不會生成所謂的可執(zhí)行文件,源文件就是可執(zhí)行文件,這句話是說給沒有腳本經驗的朋友們的聽的,解釋型語言編譯之后走哪算哪,沒有所謂的入口。
2.perl中常用的只有3種常量類型,標量、數組和散列
標量包括常用的字符串,數字,類型是不確定的,perl會根據你的上下文情景做“自然的”轉換,聲明標量使用$前綴
例如你可以寫出以下語句,輕松得到結果
$num1=5;
$num2=5**2;
print "the square of $num1 is $num2";
(結果你可以自己試試看)
而數組則是perl另一個靈活強大的類型,聲明數組使用@前綴,還是以一個例子說明吧
3, 函數參數列表的括號可加可不加,就像上面調用open函數,正規(guī)寫法應該是open(FILE,"$_[0]"),原因就在于perl覺得挪動兩根手指去輸入括號,是很費時的,而大多數情況下不加括號并不會引起歧義
4,函數的返回值為默認的最后一個表達式的值,請注意,perl的函數沒有void的類型,任何函數都有返回值,且不用你去費事的寫return,而return在perl中又叫“多余的7個字母”
5,子例程參數列表 @_的使用,你也許會對第一個例子中的子例程replaceString有的意外,沒有參數列表,是的,perl的子例程沒有參數列表,不去規(guī)定每個函數可以接受什么參數,多少個參數,所有傳入的參數都會在函數調用的時候自動存入@_這個特殊數組(諸如此類的特殊符號perl中還有許多),而數組的第一個元素可以像這樣應用$_[0],第二個$_[1]...依次類推,所以,我可以將第一個例程稍作修改,使他可以適用于更多的輸入參數,達到一次處理多個文件的效果
$_ 默認變量,多用于循環(huán)語句指代循環(huán)變量
$! 錯誤信息包含變量,當調用系統(tǒng)API出錯的時候,系統(tǒng)的錯誤信息會自動寫入這個變量
$` 正則表達式匹配前置變量
$& 正則表達式匹配變量
$' 正則表達式匹配后置變量
$1,$2,$3... 正則表達式匹配臨時變量
前面兩個我們已經見過了,后面四個都是關于正則表達式的,還是以一個例子說明吧
#! perl -w
use strict;
sub readMappingFile


{
my ($fileName)=@_;
my %mapping;
open MAPFILE,"< $fileName"
or die "can't open file $fileName:$!";
while(<MAPFILE>)

{
chomp;
if(/^(\w+)\s+/)

{

$mapping
{$1}=$';
}
}
%mapping;
}
no strict;
print $ARGV[0]." is open\n";
%mapping=readMappingFile $ARGV[0];
while(($key,$value)= each %mapping)


{
print "$key=>$value\n"
}
這個例子需要傳入一個命令行參數,該參數是個文本文件的文件名,程序將讀入文本文件的內容,將它存入散列%mapping中(以%為前綴的變量聲明未散列,相當于C++ STL中的map類型),最后將其打印出來
例如:文本內容為:
1 cnblog
2 cppblog
csdb http://blog.csdn.net/dawnbreak/
cppblog http://www.shnenglu.com/dawnbreak/
將會輸出:
1.txt is open
1=>cnblog
cppblog=>http://www.shnenglu.com/dawnbreak/
2=>cppblog
csdb=>http://blog.csdn.net/dawnbreak/
注意到各行每兩個健值之間的空格或制表符并不一樣,但是輸出格式確是一致
這篇文章前前后后寫了很長時間,決定還是先發(fā)出來,慢慢更新
假設有以下一個任務,編一個函數將一個文件中所有在尖括號中間的字符由小寫轉換為大寫,這個工作如果用c++來完成的話可能得費一番心思,來看看Perl的解決方案吧
1
#! perl -w
2
&replaceString($ARGV[0];);
3
4
sub replaceString
5

{
6
open FILE,"< $_[0]"
7
or die "can' open file:$!";
8
while(<FILE>)
9
{
10
s/\w*(<[^>]+>)/\U$1/g;
11
print ;
12
}
13
}

2

3

4

5



6

7

8

9



10

11

12

13

以上是perl的解決方案,第一句話是perl的調用語句,對于windows系統(tǒng)意義不大,第二句話是將讀入的第一個參數傳入子例程replaceString,數組ARGV用來存放命令行傳入的參數,接下來就是子例程,其中的核心語句就是s/\w*(<[^>]+>)/\U$1/g;向天書一樣,不過如果你對正則表達式熟悉的,也可以看出一些門道來,這也正是perl語言的強大之處,對于正則表達式的原生支持
學習perl,首先要忘掉C++古板的作風:
1,這里沒有main函數,perl不會生成所謂的可執(zhí)行文件,源文件就是可執(zhí)行文件,這句話是說給沒有腳本經驗的朋友們的聽的,解釋型語言編譯之后走哪算哪,沒有所謂的入口。
2.perl中常用的只有3種常量類型,標量、數組和散列
標量包括常用的字符串,數字,類型是不確定的,perl會根據你的上下文情景做“自然的”轉換,聲明標量使用$前綴
例如你可以寫出以下語句,輕松得到結果
$num1=5;
$num2=5**2;
print "the square of $num1 is $num2";
(結果你可以自己試試看)
而數組則是perl另一個靈活強大的類型,聲明數組使用@前綴,還是以一個例子說明吧
1
#! perl -w
2
$sentence = "I love c++ and perl";
3
@words = split " ",$sentence;
4
print "the sentence \"@words\" has ".@words." words\n";
輸出是the sentence "I love c++ and perl" has 5 words,是的,你也許意識到,perl自動根據你需要做了轉換,這部分涉及標量上下文和列表上下文(超出本文討論范圍,有興趣可以深入研究),是perl的一個重要特性。然而perl 數組還有許多強大特性,例如,將以上例子稍作修改如下:
2

3

4

1
#! perl -w
2
$sentence = "I love c++ and perl";
3
@words = split " ",$sentence;
4
@words = @words[0,1,4];
5
print "the sentence \"@words\" has ".@words." words\n";
有興趣的朋友可以試試看結果
2

3

4

5

3, 函數參數列表的括號可加可不加,就像上面調用open函數,正規(guī)寫法應該是open(FILE,"$_[0]"),原因就在于perl覺得挪動兩根手指去輸入括號,是很費時的,而大多數情況下不加括號并不會引起歧義
4,函數的返回值為默認的最后一個表達式的值,請注意,perl的函數沒有void的類型,任何函數都有返回值,且不用你去費事的寫return,而return在perl中又叫“多余的7個字母”
5,子例程參數列表 @_的使用,你也許會對第一個例子中的子例程replaceString有的意外,沒有參數列表,是的,perl的子例程沒有參數列表,不去規(guī)定每個函數可以接受什么參數,多少個參數,所有傳入的參數都會在函數調用的時候自動存入@_這個特殊數組(諸如此類的特殊符號perl中還有許多),而數組的第一個元素可以像這樣應用$_[0],第二個$_[1]...依次類推,所以,我可以將第一個例程稍作修改,使他可以適用于更多的輸入參數,達到一次處理多個文件的效果
1
&replaceString(@ARGV);
2
3
sub replaceString
4

{
5
foreach $id (0..@_-1)
6
{
7
open FILE,"< $_[$id]"
8
or die "can' open file $_[$id]:$!";
9
while(<FILE>)
10
{
11
s/\w*(<[^>]+>)/\U$1/g;
12
print ;
13
}
14
close FILE;
15
}
16
}
6,以上的例子還可以進一步簡化 
2

3

4



5

6



7

8

9

10



11

12

13

14

15

16

1
&replaceString(@ARGV);
2
3
sub replaceString
4

{
5
foreach (@_)
6
{
7
open FILE,"< $_"
8
or die "can' open file $_[$id]:$!";
9
while(<FILE>)
10
{
11
s/\w*(<[^>]+>)/\U$1/g;
12
print ;
13
}
14
close FILE;
15
}
16
}
注意第5行和第7行的變化,出現(xiàn)了一個新的面孔$_,它成為默認變量,那它默認指代誰呢?在循環(huán)語句中,它默認指代循環(huán)變量,注意到foreach中省略了他原有的循環(huán)變量$id,那這時$_就指向了它,也許你會覺得這回令程序產生歧義,其實這些擔心是多余的,事實上它在perl中很好用,可以使寫出來的程序簡潔優(yōu)美,perl中還有許多諸如此類的變量:
2

3

4



5

6



7

8

9

10



11

12

13

14

15

16

$_ 默認變量,多用于循環(huán)語句指代循環(huán)變量
$! 錯誤信息包含變量,當調用系統(tǒng)API出錯的時候,系統(tǒng)的錯誤信息會自動寫入這個變量
$` 正則表達式匹配前置變量
$& 正則表達式匹配變量
$' 正則表達式匹配后置變量
$1,$2,$3... 正則表達式匹配臨時變量
前面兩個我們已經見過了,后面四個都是關于正則表達式的,還是以一個例子說明吧



































這個例子需要傳入一個命令行參數,該參數是個文本文件的文件名,程序將讀入文本文件的內容,將它存入散列%mapping中(以%為前綴的變量聲明未散列,相當于C++ STL中的map類型),最后將其打印出來
例如:文本內容為:









這篇文章前前后后寫了很長時間,決定還是先發(fā)出來,慢慢更新
posted on 2009-01-14 21:30 pear_li 閱讀(2070) 評論(9) 編輯 收藏 引用 所屬分類: perl