perl語言文字處理模式

Perl語言的文字處理模式(Regular Expression)

  如果在Unix中曾經使用過sde、awk、grep這些指令的話,相信對於Perl語言中的文字處理模式(Regular Expression) 應該不會感到陌生纔對。在Perl語言中因爲有這個功能,所以對於字符串的處理能力是非常強有力的。Regular Expression可視爲用來處理字符串的一種模式(pattern),其使用的格式爲/pattern/。在Perl語言的程序設計中,經常可以看得 到類似語法的應用,在CGI程序設計中也不例外。只要能夠善用文字處理模式的話,要處理任何難的字 符串皆可迎刃而解,在本章中筆者會用深入淺出的方式來介紹Regufar Expression的用法。

一、文字處理(RegularExpression)的常用語法

  以下是文字處理模式中,/pattern/常用到的語法:

  /pattern/ 說明除了換行字符/n外,找尋只有一個字符的字符串 x? 找尋0個或是1個x字符 x* 找尋0個或是0個以上的x字符 .* 找尋0個或是0個以上的任何字符 x+ 找尋1個或是1個以上的x字符 .+ 找尋1個或是1個以上的任何字符 {m} 找尋剛好是m各個數指定的字符 {m,n}找尋在m個個數以上、n個個數以下指定的字符 {m,} 找尋m個個數以上指定的字符 [] 找尋符合[]內的字符 [^] 找尋不符合[]內的字符 [0-9] 找尋符合0到9的任何一個字符[a-z] 找尋符合a到z的任何一個字符 [^0-9] 找尋不符合0到9的任何一個字符 [^a-z]找尋不符合a到z的任何一個字符 ^ 找尋字符串開頭的字符 $ 找尋字符串結尾的字符 d找尋一個digit(數字)的字符,和[0-9]語法一樣 d+ 找尋一個digit(數字)以上的字符串,和[0-9]+語法一樣 D 找尋一個non-digit(非數字)的字符,和[^0-9]語法一樣 D+ 找尋一個non-digit(非數字)以上的字符串,和[^0-9]+語法一樣 w 找尋一個英文字母或是數值的字符,和[a-zA-Z0-9]語法一樣 w+ 找尋一個以上英文字母或是數值的字符串,和[a-zA-Z0-9]+語法一樣 W 找尋一個非英文字母或是數值的字符,和[^a-zA-Z0-9]語法一樣 W+ 找尋一個以上非英文字母或是數值的字符串,和[^a-zA-Z0-9]+語法一樣 s 找尋一個空白的字符,和[ntrf]一樣 s+ 找尋一個以上空白的字符,和[ntrf]+一樣S 找尋一個非空白的字符,和[^ntrf]一樣 S+ 找尋一個以上非空白的字符,和[^ntrf]+一樣 b 找尋一個不以英文字母、數值爲邊界的字符串 B 找尋一個以英文字母、數值爲邊界的字符串 a|b|c 找到符合a字符或是b字符或是c字符的字符串 abc找到一個含有abc的字符串 (pattern)。

   ()這個符號會記憶所找尋到的字符串,是一個很實用的語法 第一個()內所找到的字符串變成$1這個變量或是1變量 第二個()內所找到的字符串變成$2這個變量或是2變量 以此類推,筆者會在下一個小節中詳細介紹它的用法/pattern/i i這個參數是代表忽略英文大小謝的意思,也就是在找尋字符串的時候,不會去考慮英文的大小寫 如果要在pattern模式中找尋一個有特殊意義的字符,要在這個字符前加上這個符號,這樣纔會讓這個特殊字符失效。



二、文字處理模式(RegularExpression)的簡單範例

  看了上一小節文字處理模式〈RegularExpression)之後,初學者對於這個語法的應用可能 還不是很清楚,所以筆者會在這一小節中,舉出一些在文字處理模式中常用的範例給大家瞧瞧:

  範例說明:

/perl/ 找到含有perl的字符串 /^perl/ 找到開頭是perl的字符串/perl$/ 找到結尾是perl的字符串 /c|g|i/ 找到含有c或g或i的字符串 /cg{2,4}i/ 找到c後面跟着2個到4個g,再跟着i的字符串 /cg{2}i/ 找到c後面跟着2個g,再跟着i的字符串 /cg*i/ 找到c後面跟着0個或多個g,再跟着i的字符串,如同/cg{0,}i/ /cg+i/ 找到c後面跟着一個以上的g,再跟着i的字符串,如同/cg{1,}i/ /cg?i/ 找到c後面跟着0個或是一個g,再跟着i的字符串,如同/cg{0,1}i/ /c.i/ 找到c後面跟着一個任意字符,再跟着i的字符串 /c..i/ 找到c後面跟着二個任意字符,再跟着i的字符串 /[cgi]/ 找到符合有這三個字符任意一個的字符串 /[^cgi]/ 找到沒有有這三個字符任意一個的字符串 /d/找尋符合數值的字符串 可以使用/d+/來表示一個或是個多個數值的字符串 /D/ 找尋符合不是數值的字符串 可以使用/D+/來表示一個或是個多個非數值的字符串 /w/ 找尋符合英文字母、數值的字符串 可以使用/w+/來表示一個或是個多個英文字母、數值的字符串 /W/ 找尋符合非英文字母、數值的字符串 可以使用/W+/來表示一個或是個多個非英文字母、數值的字符串 /s/ 找尋符合空白的字符串 可以使用/s+/來表示一個或是更多個空白字符的字符串 /S/ 找尋符合不是空白字符的字符串 可以使用/S+/來表示一個或是更多不是空白的字符的字符串 /*/ 找尋符合*這個符號的字符串,因爲*在文字處理模式中有它的特殊意思,所以要在這個特殊符號前加上這個符號,這樣纔會讓這個特殊字符失效 /abc/i 找尋符合abc的字符串而且不考慮這些符合字符串的大小寫。


 三、文字處理模式(Regular Expression)相關的運算符及函數

  在perl程序寫作中常會用到=~和!~這兩個運算符及s和tr這二個函數來和文字處理模式/pattern/搭配而成一個運算式,如果能夠活用這些 指令的話,就可以很輕易地來處理一些字符串,當然在CGI程序設計中也就更能得心應手了。現在就讓作者來介紹這些運算符及函數的用法:

  --------------------------------------------------------------------------

指令: /pattern/文字運算
說明:如果在文字運算中沒有使用=~或是!~運算符指定一個字符串來做運算的話, 就會
使用內定的輸出變量$_來做/pattern/文字運算。

範例一:
  $string="chmod7llcgi";
  $string=~/(w+)s+(d+)/;
  第一個(w+)是代表找尋數個字母,並將所找到的字符串指派給$l這個變量,而s+代
表 找尋多個空白的字符串,最後(d+)代表找尋數個數值,並將所找到的字符串指派給
$2這 個變量。所以$l="chmod",$2=71l,但是$string還是等於原來的字符串,沒有改變。

範例二:
  $_="chmod71lcgi";
  /(w+)s+(d+)/;
  因爲是把字符串指定給$_這個變量,所以可以不用=~這個運算符就會得到
$l="chmod", $2=711;而且$_還是等於原來的字符串,沒有改變。

範例三:
  $string="chmod71lcgi";
  @list=split(/s+/,$string);
  以一個或是多個空白字符來分割$string這個字符串,這是一個很常用的語法。此時
  @list=("chmod","7ll","cgi");
指令: =~相配運算符
說明:這是Perl語言中特有的語法,通常會和文字處理模式來作運算。

範例:
  print"請輸入一個字符串!n";
  $string=<>; #<>代表標準輸入,會讓使用者輸入一字符串
  chop($string);  #將$string最後一個換行的字符n刪除掉
  if($string=~/cgi/){  
   print"輸入的字符串中有cgi這個字符串!n";
  }
  如果輸入的字符串中含有cgi這個字符串的話,就會顯示出這個信息。
  --------------------------------------------------------------------------

指令:!~不相配運算符
說明:這也是Perl語言中特有的語法,通常會和文字處理模式來作運算。

範例:
  print"請輸入一個字符串!n";
  $string=<>; #<>代表標準輸入,會讓使用者輸入一字符串
  chop($string);  #將$stdng最後一個換行的字符n刪除掉
  if($string!~/cgi/){
    print"輸入的字符串中沒有cgi這個字符串!n";
  }
  如果輸入的字符串中沒有含有cgi這個字符串的話,就會顯示出這個信息。
  --------------------------------------------------------------------------

指令:tr轉換函數
語法:tr/SEARCHLIST/REPLACELIST/
  其中SEARCHLIST是要轉換的字符,REPLACELIST是轉換成何種字符。
說明:tr(translate)就是轉換的意思,會把符合轉換的字符轉換成要轉換的字符。

範例一:
  $string="test1ng";
  $string=~tr/et/ET/;#此時$string="TEsTing";
  $string=~tr/a-z/A-Z/;#此時$string="TESTING";

範例二:
  $string="CGI+Perl";
  $string=~tr/+//;#此時$string="CGI Perl";
  在傳送CGI數據的時候會先將數據編碼,其中會將空白的字符轉成+這個字符,所以 在
解碼的時候要把+這個字符還原成空白的字符。

指令:s取代函數
語法:s/PATTERN/REPLACE/eg

  其中PATTERN是文字處理(Regular Expression)的模式,REPLACE是代表取代成何種文
字 模式。而g是這個函數最常用的參數,代表要把所有符合文字模式的字符串 全部取
代,如果省略這個參數的話,則只取代一個符合文字模式的字符串;而加上e這 個參數是代
表要將REPLACE的部分當成一個運算式,如果沒有這個需要的話,就不用加 上這個參數。
說明:將符合文字處理模式的字符串取代成爲要取代的字符串。

範例一:
  $string="i;love;perl";
  $string=~s/:/*/:   #此時$string="i*love:perl";
  $string=~s/:/*/g;   #此時$string="i*love*perl";
  $stiing=~s/*/+/g;   #此時$string="i+love+perl";
  $string=~s/+//g:   #此時$string="i love perl";
  上一行也可寫成$string=~tr/+//;效果都會一樣哦!
  $string=~s/per1/cgi/; #此時$string="i love cgi";

範例二:
  $string="i love per";
  $string=~s/(love)/<$1>/;
  第一個()內所找到的字符串變成$1,在這個範例中,會把變量love這個字符串變成
<>,此時$string="i<>perl";
  $string="i love per1";
  $string=~s/(i)(perl)/<$1><$2>/;
  在這個範例中,會把i變成<>,perl變成<>此時$string="<>love<>";
  $striag="i love per1";
  $string=~s/(w+)/<$1>/g;

  (w+)代表找尋符合一個或是多個英文字符或是數值的字符串,之後再將找到的字 符串設成$l。因爲加上g這個參數,所以會找到字符串中的這三個英文單字, 然後 再把這三個單字分別加上<>這個符號,此時$string="<><><>";

範例三:
  $string="ww22cgi44";
  $string=~s/(d+)/$1*2/e;
  (d+)代表要找尋$string中一個或是多個數值的字符串,再將找到的字符串設成
$1。加上參數e是代表要把$l*2當作是一個運算式,所以$string="www44cgi44";
  $string="www22cgi44";
  $string=~s/(d+)/$1*2/eg;
  加上參數e,所以會把$1*2當作是一個運算式來看, 加上參數g就會把全部符合數 值
的字符串經過運算式運算之後再把它取代,所以$string="www44cgi88";

範例四:
  假設原本的字符串是$value="三八!",經CGI數據編碼之後,這個字符串就會變成
$value="%A4T%A4K%21"。以下是一個解碼的示範程序:
  $value="%A4T%A4K%2l";
  $value=~s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($l))/eg;

  在傳送CGI數據的時候會把數據編碼,其中會將特殊字符或是中文字符編碼成以% 開頭的連續兩個十六進制數的字符串,所以要用s這個函數來找尋這個以%開頭的 字符串。爲了要把找到的字符串再做解碼的處理, 所以要在%這個符號之後加上 ()這個符號, 表示會把找到的字符串記憶起來並指定給$1這個變量,而且要在() 中加上代表是連續兩個十六進制數值的文字處理模式(Regular Expression),也 就是[a-fA-F0-9][a-fA-F0-9]。再用hex這個函數($1是代表符合的字符串)把十 六進制數值轉成十進制的碼,之後再用pack這個函數(以C爲參數,是代表 unsigned char value的意思)把這個十進制碼還原成原來的字符串。最後就會 把這個字符串解碼成$value="三八!"。值得一提的是也可以把這個解碼的程序 寫成:

  $value=~s/%(..)/pack("C",hex($l))/eg;

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