自動目錄
在前面有提到過樣式後面的修飾子 'g',接下來深入探討更多的修飾子。
不分大小寫比對
使用 'i' 修飾子可以在比對時忽略大小寫,i是ignore的意思,這個只會忽略英文字母的大小寫。
$str = "When and how is John doing?"; if( $str =~ /when/i ){ print $& ."\n"; #When }
第2行 多了一個 i作修飾子,所以 When會和when比對成功並傳回'When'
中文字的比對
中文字的比對和非中文的比對相同,可以直接把中文字串放入即可,perl會自動判斷編碼,沒什麼問題。若要強調比對 utf-8編碼(其實是unicode)的話,可以加上 'u' 或是 'a' 的修飾子,這兩個的差異僅在於 'a'會把ascii的字元就視為ascii的字元,而不會再轉成unicode比對 [1]。
$str = "這場探討未來網路發展的世界級會議,最近剛於瑞士日內瓦落幕。 會議中,除了討論美國政府最近收回網路中立成規的決定, 對數位媒介演進太過迅速,可能造成保存問題的憂慮。"; if( $str =~ /數位媒介/a ){ print $& ."\n"; # 數位媒介 }
第1~3行 這個字串分成三行,在每個行尾都有隱藏的 '\n'字元
第4行 使用了a修飾子指定把除了ascii的字元外的字元都視為unicode字元。
由於PERL會自動判斷編碼,事實上就算省略了這個a也能正確的判斷,但為了避免不必要的意外,遇到中文字還是建議加上。
比對的內容含有換行時,把換行也考慮進來
在上面的範例中,字串可能因為換行的關係而切斷,在比對時就會被忽略導致非預期的結果,舉例來說,下面字串中「網路」兩個字可能因為文章的寬度緣故被拆成兩行,實際上網路兩字中間還多了一個換行\n的符號:網\n路
$str = "這場探討未來網
路發展的世界級會議";
假設我們拿來比對字串「網路」,就會發現比對失敗。為了增加比對的正確性,比對時也要把可能被拆開的字串進行判斷:
$str = "這場探討未來網 路發展的世界級網路會議"; if( $str =~ /網\n?路/a){ print $& ."\n"; }
第3行 比對字串中網路兩字中間加了一個\n?,代表判斷換行的有無。
結果
網
路
中文字麻煩的地方,也可以說是方便的地方,就是可以斷在任何地方,如果是二個字的詞就只有一種斷法,三個字的詞就會有三種斷法,n個字的詞就會有2(n-1)-1種斷法,比較偷懶的比對就是把所有的換行都先置換掉再來比對,缺點是內容很長會不知道這到底是原文的哪裡?因為換行都被抽掉,位置是抽掉後的結果。不然就是每個字和字中間都加上'\n?' 來作樣式,因為這是門困難的科學,所以略過不提。
一個unicode中文字代表三個字元
中文字的比對要注意,一個unicode中文字代表三個字元,例如:
if( $str =~ /長.鹿/a){ print "比對成功"; }
在這範例中是不會比對成功的,除非你把'.'改成'.{3}'
if( $str =~ /長.{3}鹿/a){ print "比對成功"; }
把換行視為一個字元
使用 's' 修飾子可以在比對時把換行也當成一個字元來處理,沒有加s的話,比對任何一個字元 '.' 會忽略換行。
$str = "John is a boy, Mary is a girl. They are friends."; while( $str =~ /is.a/sg){ print $& ."\n"; }
說明
第3行 修飾子用's'讓換行可以比對成功,在while中要加入修飾子'g'以免造成無窮迴圈。
結果
is a
is
a
如果上面沒加上 修飾子's',比對出來結果只會有一個:
is a
把字串視為多行來比對
使用 'm' 修飾子可以在比對時把換行也當成一個字元來處理,這對多行的文比對很有用。這時候代表開始的記號'^'和結束的記號'$'就會判斷每一行的頭和尾,如果沒加m的話,就只會判斷一開始和結束。
$str = "Sweater costs 200 dollars Shirt is 300 dollars Pants are 400 Stockings are 100 dollars"; while( $str =~ /\d+ dollars$/g){ print $& ."\n"; }
結果
100 dollars
上面的例子中,因為在樣式中比對出行尾有 "數字 dollars"的內容,所以會把整個字串中的換行算成字串的一部分。
如果加上了 'm' 修飾子,在判斷時就會每個換行都當成一行來判斷,同樣的,在while中要加入修飾子'g'以免造成無窮迴圈。
結果
200 dollars
300 dollars
100 dollars
Perl的修飾子很多,剩下的到取代章節再來談。
上一篇 14-進階比對 #1--取回比對內容
回到目錄 01-撰寫第一隻PERL程式
下一篇 16-字串取代和置換
參考資料
[1] https://perldoc.perl.org/perlre.html