PERL學習筆記---正規表示式的應用

wangyy發表於2014-06-13

 使用m//匹配

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

不區分大小寫:/i

if(/yes/i) {#大小寫無關

print “In that case, I recommend that you go bowling.\n”;
}

 

匹配任何字元:/s

預設情況下,點(.)不匹配換行符,這對於“單行中查詢”的問題能很好解決。如果你的字串中有換行符,並希望點(.)能匹
配它們,那可以使用/s 這個修飾符。它將模式中點(.)◆的行為變成同字元類[\d\D]的行為類似:可以匹配任何字元,包括換
行符。從下例中可見其區別:
◆如果你想改變其中的一部分,但不是全部,那可以將此部分用[\d\D]代替

$_ = “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”;
}
如果不使用/s,那麼上述模式將不能被匹配上,因為這兩個字元不在同一行中。

 

符號^(脫字字元◆)表示在字串的開頭進行匹配,而符號$則表示在結尾◆。因此,模式/^fred/只匹配字串的開頭部分;
它不會匹配上manfred man。而/rock$/只在結尾處匹配;其不會匹配上knute rockne。

錨定不僅僅針對字串的兩頭。詞界錨定,\b,是針對單詞使用的。如/\bfred\b/可以匹配上單詞fred,但不能匹配frederick,
alfred, man fred mann。這同字處理軟體中的“全字匹配(match whole words only)”是類似的。
◆某些正規表示式實現中開頭的錨定和結尾錨定不同,但Perl 中均使用\b。
這些單詞(words)不是你或者我通常認為的那樣;它們是\w 型別,由通常的字母,數字,下劃線組成。\b 將從開頭或結尾
匹配這些\w 型別的字元。

非詞界錨定為\B。它將在任何非\b 匹配的點上進行匹配。因此,模式/\bsearch\B/將匹配searches, searching, searched, 但不能
匹配search,或者researching。

 

 

繫結操作符(binding operator:=~)

),$likes_perl 將根據使用者的輸入而得到一個boolean 值。它有一些quick-and-ditry,因為輸入
行很快就被丟棄了。這段程式碼將讀入一行,由右邊的模式進行匹配,然後丟棄此輸入◆。它沒有使用$_。
◆輸入的字元不會自動儲存在$_中,除非行輸入操作(<STDIN>)單獨出現在while 迴圈的條件判斷部分。
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”;

}
由於繫結操作有非常高的優先順序,因此,模式測試部分的括號不是必需的,下面的程式碼和上面程式碼的含義是一樣的。它將
測試部分的結果(而非行輸入)返回給變數$likes_perl:
my $likes_perl = <STDIN> =~ /\byes\b/i;

其含義是:“這個模式預設將對
$_進行匹配,但此時將對左邊的字串進行匹配”。如果沒有繫結操作符,則此表示式將對$_匹配。

 

 

匹配變數
我們曾經在模式中使用過括號,使用括號是由於它可以將模式的某一部分組合起來。同時括號也會引起正規表示式分配新
的記憶體塊。這些記憶體含有括號中的模式所匹配的字串。如果有不止一對括號,那就不止一塊記憶體塊。每一個記憶體塊內有
一段字串,而非模式的一部分。
由於這些變數含有字串,那它們是標量變數;在Perl 中,它們具有像$1, $2 這樣的名字。變數個數同模式中括號對數的個
數是相同的。如$4 是指第四對括號所匹配的字串◆。
◆這和後引用(backreference)\4 在模式匹配中引用字元的字串相同。但它們不僅是同一事物的兩個不同名字;\4 是模式正在匹配是引
用的;而$4 是模式匹配完成後再引用的。想了解更多的關於backreferences 的資訊,可參見perlre 的幫助手冊。
這些匹配變數(match variables)是組成正規表示式強大功能的重要部分,它允許取出相應的字串:
$_ = “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。注意輸出中沒有逗號。因為第二塊記憶體中沒有逗號。使用這種技術,可以選擇
我們感興趣的部分。

匹配變數可能是空的◆,如果其沒有被匹配上。也就是說,匹配變數的值可能為空串:
◆這和undefined 是不同的。如果模式中只有3 個或者更少的括號,那$4 為undef。
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"; # 空串
}

 自動匹配變數

if(“Hello there, neigbor”=~ /\S(\w+),/){
print “That actually matched ‘$&’.\n”;
}
匹配的部分是“there,”(空格,單詞,和一個逗號)。變數$1 中的值為there,而$&為整個被匹配的部分。
匹配部分的前一部分存放在$`之中,後一部分被存到$'。另一種說法是,$`中含有正規表示式引擎在匹配成功前所找到的變
量,而$'為此模式還沒有匹配的剩餘部分。如果將這三個變數放在一起,你將得到原始字串:
if (“Hello there, neighbor”=~ /\S(\w+),/){
pirnt “That was ($`)($&)($’)”;
}

 

輸出的訊息為(Hello)( there,)( neighbor),為這三個自動匹配變數的值。三個變數的值可能是空的,和之前數字匹配變數的例
子一樣。它們和數字匹配變數有相同的作用域。通常,在下次成功匹配前其值不變。

 

相關文章