perl學習日記8正則表達式的應用

 

1.1      使用m//匹配

這是m//(模式匹配)的一種簡寫。同qw//操作一樣,可以使用任何成對的分隔符。因此,可以使用m(fred)m<fred>m{fred}m[fred],或者m,fred,m!fred!m^fred^,其它非成對的分隔符也可以。

如果使用正斜線(/)作爲分隔符,則可以省略掉前面的m。這就是前面用的最多的。

 

儘量使用一個不會在模式中出現的字符作爲分隔

1.2      可選的修飾符

1.2.1.      不區分大小寫:/i

1.2.2.      匹配任何字符:/s

 

默認情況下,點(.)不匹配換行符,這對於單行中查找的問題能很好解決。如果你的字符串中有換行符,並希望點(.)能匹配它們,那可以使用/s 這個修飾符。

$_ = “I saw Barney/ndown at the bowing alley/nwith Fred/nlast night./n”;

if(/Barney.*Fred/s){

print “That string mentions Fred after Barney!/n”;

}

1.2.3.      添加空格:/x

/-?/d+/.?/d*/ #這是什麼含義?

/ -? /d+ /.? /d* /x #要好些

 

主要就是增加可讀性,但不改變語義

1.2.4.將可選字符結合起來

if(/barney.*fred/is){ # /i /s 書上寫錯了,多了一個(/)

print “That string mentions Fred after Barney!/n”;

}

1.3      錨定

模式/^fred/只匹配字符串的開頭部分;它不會匹配上manfred man。而/rock$/只在結尾處匹配;其不會匹配上knute rockne

 

在模式中^,有其它的用途。在字符類中,如果將其放在最前面,將會得到此集合的補集。

 

記住/^fred$/能同時匹配上fredfred/n

 

注意是整個字符串的結尾和開頭,不是某個單詞的結尾我開頭。

 

有時,想同時使用這兩個錨定來確保匹配整個字符串。一個經常使用的例子是/^/s*$/,它將匹配一個空行(blank line)。這裏的“blank(空白),可以是空白符,如製表符,空格等,它們是不可見的。能被匹配上的行看起來都是一樣的,因此這個模式將所有的空白按一種方法來處理。如果沒有錨定,則它還會匹配上非空行。

1.3.1.詞錨定

詞界錨定,/b,是針對單詞使用的。如//bfred/b/可以匹配上單詞fred,但不能匹配frederick,

Alfred

 

詞是字母,數字,下劃線組成的序列。這種意義下的詞可由//w+/匹配上。下句中有個詞:That,s,a,word,以及boundary。詞上的引號不會改變詞界的位置;這些詞是由/w 字符組成的。

 

以上劃線的就是“詞” /b 只匹配這樣的詞

 

當使用//bhunt/ 將匹配上像hunthuntinghunter,這樣的單詞,但不會匹配shunt,而/stone/b/將匹配sandstoneflintstone,而不能匹配上capstones

1.4      綁定操作符,=~

my $some_other = “I dream of betty rubble.”;

if($some_other =~ //brub/){

print “Aye, there’s the rub./n”;

}

其含義是:“這個模式默認將對$_進行匹配,但此時將對左邊的字符串進行匹配”。

 

print “Do you like Perl? ”;

my $likes_perl = (<STDIN> =~ //byes/b/i);

… #Times passes…

if($likes_perl){

print “You said earlier that you like Perl, So… /n”;

}

 

my $likes_perl = <STDIN> =~ //byes/b/i;    #一樣正確,因爲~的優先級高

1.5      模式內的內插

#! /usr/bin/perl –w

my $what = “larry”;

while(<>){

if(/^($what)/){ #在字符串前面進行匹配

print “We saw $what in beginning of $_;”;

}

 

也可以從程序參數讀取模式

my $what = shift @ARGV;

 

/^(fred|barney)/:在行首查找fred 或者barney。括號(在查找larry 的例子中不是必須的)是非常重要的,如果沒有它,則在行首查找fred,或在此行中任意位置查找barney

如果$wha的值爲fred(barney,這個模式是/^(fred(barney)/。上述模式是不能工作的,會由於錯誤使用正則表達式而使程序垮掉。

 

1.6      匹配變量

$_ = “Hello there, neighbor”;

if(//s(/w+),/){ #空格和逗號之間的詞

print “the word was $1/n”; #the word was there

}

 

$_ = “Hello there, neighbor”;

if(/(/S+) (/S+), (/S+)/){

print “words were $1 $2 $3”;

}

其輸出爲words were Hello there neighbor

 

my $dino = "I fear that I'll be extinct after 1000 years.";

if ($dino =~ /(/d*) years/) {

print "That said '$1' years./n"; # 1000

}

my $dino = "I fear that I'll be extinct after a few millions years.";

if ($dino =~ /(/d*) years/) {

print "That said '$1' years./n"; # 空串     暫沒弄清楚爲啥$1有單引號,如果打印$2會怎樣?是不是因是undef而顯示(哈批,因爲它想打印單引號出來,$2也是打印空串)

}

 

1.6.1.內存值的保存

這些匹配變量的值會保持不變,直到下一個模式成功匹配爲止

但是如果想在過幾行之後再用$1是非常不好的習慣,如果調試人員在這之間又加了模式匹配,就發生了錯誤。

1.6.2.自動匹配變量

if (“Hello there, neighbor”=~ //S(/w+),/){

pirnt “That was ($`)($&)($’)”;

}

變量$1 中的值爲there,而$&爲整個被匹配的部分,注意不再是限於括號了。匹配部分的前一部分存放在$`之中,後一部分被存到$',所以輸出的消息爲(Hello)( there,)( neighbor)

 

這裏的代價是,如果你使用了這三個自動匹配變量中的任意一個,無論在程序的什麼地方,其它地方的正則表達式的運行數度會變慢一些。雖然,變慢的程度不大,但已經足夠讓人擔憂,因此許多Perl 程序員從不使用這些自動匹配變量。相反的,使用的替代的方法。例如,如果需要使用$&,那麼在整個模式上加上括號,並使用$1 代替。

1.7      一般的數量詞

模式/a{5,15}/將匹配個到15 中的任意一個(包括5,和15

/(fred){3,}/將在一行中有個或者更多個fred 時匹配上(fred之間不允許有其它字符,包括空格)

//w{8}/將嚴格的匹配word(字母,數字,下劃線)(可能被其中一個長字符串部分所匹配上)

1.8      優先級

1.在此優先級表的最頂端是括號:(()),在分組和引用內存值的時候使用。括號內部的任何部分比括號外的部分結合更緊密。

2.第二級是數量詞。這裏有星號(*), 加號(+),問號()以及由花括號表示的數量詞,如{5,15}{3, }{5}等。它們通常和前一項元素結合。

3.第三級的是錨定和序列(sequence)。錨定包括(^表明字符串的開頭,($)表明結尾,(/b)詞界符,(/B)非詞界符。序列(一個元素緊接着一個元素)實際上是一種操作,雖然它沒有使用元字符。這段話的含義是一個單詞中的字母結合更緊密,就像錨定緊貼字母一樣。

4.優先級最低的是豎線(|),表示或。由於其優先級最低,它通常將模式劃分成幾個部分。它在優先級最底端是因爲我們希望像|/fred|barney/裏面的字母比或(|)結合更緊密。如果或(|)的優先級比序列的優先級更高,那麼,上述模式的含義是匹配fre,接着是或者b然後是arney。因此,或(|)的優先級最低,字母序列的優先級要高些。

1.8.1.優先級練習

例如,/^fred|barney$/很可能並不是程序員想要的模式。由於豎線(|)的優先級最低;它將上述模式分成了兩部分。這個模式在或者開頭是fred,或者結尾是barney 時匹配上。很可能程序員想要的是(^(fred|barney)$,這將匹配只有fred 或者只有barney的行◆。那/(wilma|pebbles?)/呢?問號也對前面的元素有效◆,它將匹配wilmapebbles或者pebble,可能是某個長字符串的一部分(因爲沒有錨定)。

當然,結尾處可以有換行符,我們在早期討論$錨定時提到過。

因爲數量詞?和字母結合更緊密

1.9      模式測試程序

#! /usr/bin/perl

while(<>){ #一次取一行輸入

chomp;

if(/YOUR_PARTTEN_GOES_HERE/){

print “Matched: |$`<$&>$’|/n”; #特殊的變量

}else{

print “no match: |$_|/n”;

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章