9.1搜尋標量
用index進行搜尋
index string,substring
index string,substring,start_position
index函數從string的左邊開始運行,並搜尋substring.返回找
到substring所在的位置。0是指最左邊的字元,如果沒有找到s
ubstring,index便返回-1;如:
index "Ring around the rosy","around"; #返回5
index("Pocket full of posies","ket"); #返回3
index "ddd","ff"; #返回-1
index("test test","test",1); #返回5
也可以使用帶起始位置的index函數,以以便“遍曆”一個字元
串,找到出現一個較短字串的所有位置,如:
$source = "One fish,two fish,red fish,blue fish.";
$start =-1;
while (($start=index($source,"fish",$start)) !=-1) {
print "Found a fish at $start/n";
$start++;
}
rindex向後搜尋 與index基本相同 不過它是從右向左進行搜尋
,如:
$a="She loves you yeah, yeah, yeah.";
rindex($a,"yeah"); #返回26.
rindex($a,"yeah",25); #返回20
但它的遍曆和index有點不同,它的起點必須從字元的結尾開始
。當然也是遞減1而不是加1了,如:
$source = "One fish,two fish,red fish,blue fish.";
$start =length($source);
while (($start=rindex($source,"fish",$start)) !=-1) {
print "Found a fish at $start/n";
$start--;
}
substr分割標量,句法如下:
substr string,offset
substr string,offset,length
substr函數取出string,從位置offset開始運行,並返回從off
set到結尾的字串的剩餘部分,如果設定了length,那麼取出
length指明的字元,或者直到找出字串的結尾,以先到者為
准,如
$a="I do not like green eggs and ham.";
print substr($a,25); #輸出 and ham.
print substr($a,14,5); #輸出 green"
如果offset為負值,substr函數將從右邊開始計數,如substr(
$a,-4)返回$a的最後4個字元;如果length為負值,則substr返
回從它的起點到字串結尾的值,如
print substr($a,5,-10); #輸出 not like green egg
也可以使用賦值運算式左邊的substr函數,當用在左邊時,sub
str用於指明標量的什麼字元將被替換,當用在賦值運算式的左
邊時,substr的第一個參數必須是個可以賦值的值,比如標量
變數,而不是應該是個字串直接量,如下:
$a="countrymen,lend me your wallets";
#第一個字母用"n3tl04d,c"代替
substr($a,0,1)="n3tl04d,c";
#在前面插入"Bl,"
substr($a,0,0)="Bl,";
#替換最後7人字元
substr($a,-7,7)="ears.";
tr///(y///)轉換符,句法如下:
tr/searchlist/replacementlist/
例
tr/abc/xyz/; #In $_,把abc變為xyz
$r=~tr/abc/xyz/; #一樣,只是用$r
tr/A-Z/a-z/;
如果replacementlist是空的,或者與searchlist相同,那麼tr
///將計算並返回匹配的字元。目標字串並不被修改,如:
$potato="dldii";
$eyes=$potato=~tr/i//;
#計算在$potato中i的個數,返回$eyes 這裡是2
$nums=tr/0-9//; #計算在$_中的數字,返回給$nums 這裡是0
printf 功能強大的輸出函數,句法如下:
printf formatstring,list
printf filhandle formatstring,list
formatstring是一個描述輸出格式的字串,list是一個你想
讓printf顯示的值的列表。
%-w.dx
解釋:
% 域限定符標記
- 減號(可有可無)有的話輸出為靠左對齊
w 域的總寬度(必須有)
. 小數點(可有可無)
d 小數點後邊的位元(可有可無)
x 域類型(必須有)x說明符前面的連字號表示該域在w字元中
靠左對齊,否則它進行靠右對齊
只有%和x是不可少的,部分資料(域)類型如下:
c 字元
s 字串
d 十進位整數,截尾的小數
f 浮點數
部分例子:
printf("%20s","Jason"); #靠右對齊輸" Jason"
printf("%-20s","Small"); #靠左對齊輸出"Small "
$amt=7.12;
printf("%6.2f",$amt); #輸出" 7.12"
$amt1=7.127;
printf("%6.2f",$amt1); #輸出" 7.13"
printf("%c",65); #輸出"A" ASCII碼
$amt2=9.4;
printf("%6.2f",$amt2); #輸出" 9.40"
printf("%6d%",$amt2); #輸入" 9"
同時也可以
printf("%6d %4c",$a,$b);
9.5 堆棧形式
push target_array 將項目壓入堆棧
pop target_array,new_list 將項目從堆棧頂部取出
shift target_array 從底部取出元素
unshift target_array,new_list 將元素添加到堆棧的底部
注意堆棧底部為元素0,堆棧頂部是數組中的最後一個元素
例:
@band=qw(trombone);
push @band,qw(ukulele clarinet);
#@band中包含trombonem,ukulele,clarinet
$brass=shift @band; #從底取出trombone
$wind=pop @band; #從頂取出clarinet
#現在@band只有ukulele了
unshift @band,"harmonica"; #從底部添加harmonica
拼接函數 splice ,句法如下:
splice array,offset
splice array,offset,length
splice array,offset,length,list
splice用於刪除數組中從offset位置開始的元素,同時返回被
刪除的數組元素,如果offset是負值,則從數組的結尾處開始
計數,如果設定length,那麼只刪除length指定的元素,如果
設定list,則刪除指定的元素,並用list的元素取代之。如:
@veg=qw( carrots corn );
splice(@veg,0,1); #@veg is corn
splice(@veg,0,0,qw(peas)); #@veg is peas,corn
splice(@veg,-1,-1,qw(barley,turnip)); #veg is
peas,barley,turnip
splice(@veg,1,1) #@vegis peas,turnip
十、檔案與目錄
擷取目錄列表函數
opendir dirhandle,directory;
目錄控制代碼dirhandle應該全部使用大寫字母
readdir dirhandle;讀取它的內容
closedir dirhandle;關閉
下面是讀取一個目錄的例子,不包含..和.
opendir(TEST,'/') || die "Cannot open /:$!";
@FILES=grep(!/^/./.?$/,readdir TEST); #去掉..和.
closedir(TEST);
如果要尋找有特定副檔名的全部檔案,可以使用:
@FFILES=grep(//.txt$/i,readdir(TEST);
注意,readdir返回的檔案名稱並不包含opendir使用的路徑,所
以下面例子可能無法運行:
opendir(TEST,'/test') || die "Cannot open /:$!";
while($file=readdir TEST)
open(FILEH,$file) || "Cannot open $file:$!/n";
}
應該改為open(FILEH,"/test/$file") || "Cannot open
$file:$!/n";
另一種讀取目錄是用globbing,句法如下:
glob pattern
pattern是你要匹配的檔案名稱模式
字元 匹配模式 舉例
? 單個字元 f?d用於匹配fud、fid和fdd等
* 任何數目字元 f*d用於匹配fd、fdd和food等
[chars] 任何一個chars f[ou]d用於匹配fod和fud
{a,b, } a或b f*{txt,doc}匹配以f開頭且以txt或
doc結尾的檔案
建立和刪除目錄
mkdir newdir,permissions; 建立目錄,成功返回真,否則返
回假,並將$!設定為mkdir運行失敗的原因。如:
print "Directory to create?";
my $newdir=<STDIN>; chomp $newdir;
mkdir ($newdir,0755) || die "Failed to create
$newdir:$!";
rmdir pathname;刪除目錄
unlink list_of_files; 刪除檔案unlink能刪除list_of_files
中的所有檔案,並返回已經刪除的檔案數量,如果list_of_fil
es被省略,$_中指定的檔案將被刪除,要檢查檔案清單是否已
被刪除,必須對想要刪除的檔案數量與已刪除的檔案數量進行
比較,如下:
my @files=<*.txt>;
my $erased=unlink @files;
#被刪除的檔案數量存放在$erased中
if ($erased !=@files) { #與@files元素數量比較,
print "Files failed to erase:",
join(',',<*.txt>),"/n"; #不同,輸出沒有
被刪除的檔案
}
rename oldname,newname;
檔案改名如果只設定路徑,那麼rename會將檔案從一個目錄移
到另一個目錄。
chmod mode,list_of_files;更改許可權,只在unix中有用,如
chmod 0755,'test.pl';
十一、系統之間的互通性
1.system()函數,句法如下:
system command;不能捕獲輸出,如:
system("dir /w");
如要啟動一個圖形檔案編輯器:
system("notpad.exe test.txt");
2.捕獲輸出
可以使用反引號(``)括起來的任何命令均作為外部的命令來運
行,就象通過system啟動並執行一樣,其輸出被捕獲,並且作為反
引號的傳回值 ,如:
$directory=`dir`; #運行dir命令
還有一種可以代替反引號的方法,就是使用qx{},其實也可以
用qx<>,qx(),qx[],如:
$perldoc=qx{perldoc pero};
代碼可移植性
查看目錄空間
my(@dir,$free);
@dir=`dir`;
$free=$dir[$#dir];
$free=~s/.*([/d,]+) /w+ free/$1/;
$free=~s/,//g;
判斷作業系統
if ($^O eq 'MSWIN32') {
#執行window下的代碼
} elseif ($^O eq 'linux') {
#招行linux的代碼
}
十二、沒怎麼看
十三、引用和結構
引用有點象指標,如
$ref=/$a; #建立一個引用到$a
$ref中並不包含用於它自己的任何資料,它只是對$a的一個引
用。若要通過$ref來輸出$a的值,可以用:
print $$ref;
如果通過引用來修改原始值,可以用:
$$ref="sticks";
對數組的引用也同樣
$aref=/@arr;
$$aref[0] @arr的第一個元素,也可以${$aref}[0]
@$aref[2,3] @arr的一個片
@$aref @arr的整個數組
對雜湊結構的引用
$href/%hash;
$$href{key}
訪問%hash中的一個關鍵字,也可以是${$href}{key}
%$href 訪問整個雜湊結構,也可以是%{$href}
若要迭代通過該雜湊結構,輸出所有的值,可以使用:
foreach $key (keys %$href) {
print $$href{key};
}
作為參數的引用
結構
perl不支援二維數組,但可以使用數組的數組,如:
@list_of_lists=(
[qw(11 12 13)],
[qw(21 22 23)],
[qw(31 32);,
);
$list_of_lists[0][1]; #也就是11
要知道最外層列表中的元素數目:
$#list_of_lists; #最後一個是2個元素
scalar(@list_of_lists); #行數是3行
要遍曆列表,可以使用下面代碼:
foreach my $outer (@list_of_lists) {
foreach my $inner (@{$outer}) {
print "$inner";
}
print "/n";
}
可以添加下面的結構:
push(@list_of_lists,[qw(41 42 43)]); #添加一行
push(@{$list_of_lists[0]},qw(14)); #在第一行添加新
元素
十四、模組的使用
其它都是看使用說明就差不多了
最簡單的ping
#!/usr/bin/perl -w
use strict;
use Net::Ping;
if (pingecho ("www.163.com",15)) {
print "163 is on the network.";
} else {
print "163 is unreacheable.";
}
diagnostics模組能夠協助你尋找程式中的錯誤。
有關網站
www.cpan.org
十五、瞭解程式的運行效能
1.DBM檔案
DBM檔案是已經與一個perl的雜湊結構串連起來的檔案。若要讀
取和寫入DBM檔案,只需對一個雜湊結構進行操作即可,如:
dbmopen(hash,filename,mode)
提供的filename實際上在硬碟上建立兩個不同的檔案,即filna
md.pag和filename.dir,但不是文字檔。如果是linux系統,
mdoe 一般是0664。例:
dbmopen(%hash,"dbmfile",0664) || die "Can't open DBM
dbfile:$!";
$hash{feline}="cat";
$hash{canine}="dog"; #賦值
print $hash{canine}; #取出
dbmclose(%hash); #關閉串連
注意:
·關鍵字和資料長度受限制,雖然雜湊結構不受限,關鍵字和
資料合起來不能超過1024Byte
·運行dbmopen以前的雜湊結構中的值均被丟失,最好只使用新
的雜湊結構,如下例:
%h=();
$h{dromedary}="camel";
dbmopen(%h,"database",0664) || die "Cannot open:$!";
print $h{dromedary}; #輸出為空白
dbmclose(%h);
·dbmopen函數執行後,與DBM檔案相串連時雜湊結構的值將會
消失:
dbmopen(%h,"database",0664) || die "Cannot open:$!";
$h{dromedary}="camel";
dbmclose(%h);
print $h{dromedary}; #輸出為空白
遍曆
dbmopen(%recs,"records",0664) || die "Cannot open:$!";
while ( ($key,$value)=each %recs) {
print "$key=$value/n";
}
dbmclose(%recs);
15.鎖定檔案,反正就是為了讀寫出錯。
use Fcntl qw(:flock);
flock(FILEHANDLE,lock_type);
lock_type可以使用的一些值:
·lock_SH 這個值要求在檔案上設定公用鎖
·lock_EX 這個值要求對已經開啟而用於寫入的檔案設定一個
專用鎖
·lock_UN 這個值用於釋放一個鎖,很少用
例,在加鎖情況下文字檔的輸入/輸出
#!/usr/bin/perl -w
use strict;
use Fcntl qw(:flock);
my $semaphore_file="/tmp/list154.sem";
#通用鎖函數
sub get_lock {
open(SEM,">$semaphore_file") || die "Cannot
create semaphore:$!";
flock(SEM,LOCK_EX) || die "Lock failed:$!";
}
#通用解鎖函數
sub release_lock {
close(SEM);
}
sub readdata {
open(PH,"phone.txt") || die "Can't open
phone.txt $!";
my(@DATA)=<PH>;
chomp(@DATA);
close(PH);
return(@DATA);
}
sub writedate {
my(@DATA)=@_;
open(PH,">phone.txt") || die "Can't open
phone.txt $!";
foreach (@DATA) {
print PH "$_/n";
}
close(PH);
}
my @PHONEL;
get_lock();
@PHONEL=readdata();
push(@PHONEL,"N3tl04d 12345678");
writedate(@PHONEL);
release_lock();
sleep的問題
在寫shell程式的時候,經常想要在某一時刻sleep一段時間,但是unix的sleep命令的時間單位最小是秒,有時候不能滿足我們的精度要求。這時候可以調用perl的一個命令,來達到目的。
perl -e 'select(undef, undef, undef, 0.001);'
以上表示sleep 0.001秒,也就是1毫秒,select函數最小可以精確到0.000001,也就是1微妙