韌館-LearnHouse

[PHP]preg_match_all與正規表示法

自從畢業以後,比較有閒開始在注意黃金與外幣,這段期間黃金一直居高不下,一直等不到適合的進場時間。剛好遇逢近日台幣走揚,美元相對走弱。雖然前陣子我是已經進場了,但美元還是持續疲軟,所以我也只能放著。此時我還關注其他國家的貨幣,因此就決定寫一個網頁,將台灣銀行上面的所有貨幣截取出來以方便直接觀看。

此時想到最好的工具應該就是php了,已經有兩年沒碰php,突然間覺得有點生疏,上網找到比較適合用來擷取網頁資訊的函式就屬preg_match_all,該函數需要五個參數,其中一個是選用的,因此大多使用四個參數,第一個參數pattern,是用正規表示法規則來整體剖析比對字串 subject。第二個參數subject即為要比對的字串內容,第三個參數matches是將比對結果傳回的值放在陣列。
其實我現在還是有點一似懂非懂,但我還是整理了以下不錯的資料讓大家比較一下:

1.首先先要了解什麼是正規表示法,網路上零零總總的講解,似乎只會讓人更一頭霧水。因此第一次接觸的人我覺得鳥哥所寫的正規表示法會讓人比就容易懂,如果大致都了解後,再來做個種整理正規表示發列表

字元 說明 簡單範例
\ 避開特殊字元 /A\*/ 可用於比對 "A*",其中 * 是一個特殊字元,為避開其特殊意義,所以必須加上 "\"
^ 比對輸入列的啟始位置 /^A/ 可比對 "Abcd" 中的 "A",但不可比對 "aAb"
$ 比對輸入列的結束位置 /A$/ 可比對 "bcdA" 中的 "A",但不可比對 "aAb"
* 比對前一個字元零次或更多次 /bo*/ 可比對 "Good booook" 中的 "booo",亦可比對 "Good bk" 中的 "b"
+ 比對前一個字元一次或更多次,等效於 {1,} /a+/ 可比對 "candy" 中的 "a",但不可比對 "caaandy"
? 比對前一個字元零次或一次 /e?le?/ 可比對 "angel" 中的 "el",但不可比對 "angle"
. 比對任何一個字元(但換行符號不算) /.n/ 可比對 "nay, an apple is on the tree" 中的 "an" 和 "on",但不可比對 "nay"
(x) 比對 x 並將符合的部分存入一個變數 /(a*) and (b*)/ 可比對 "aaa and bb" 中的 "aaa" 和 "bb",並將這兩個比對得到的字串設定至變數 RegExp.$1 和 RegExp.$2。
xy 比對 x 或 y /a*b*/g 可比對 "aaa and bb" 中的 "aaa" 和 "bb"
{n} 比對前一個字元 n 次,n 為一個正整數 /a{3}/ 可比對 "lllaaalaa" 其中的 "aaa" 但不可比對 "aa"
{n,} 比對前一個字元至少 n 次,n 為一個正整數 /a{3,}/ 可比對 "aa aaa aaaa" 其中的 "aaa" 及 "aaaa" 但不可比對 "aa"
{n,m} 比對前一個字元至少 n 次,至多 m 次,m、n 均為正整數 /a{3,4}/ 可比對 "aa aaa aaaa aaaaa" 其中的 "aaa" 及 "aaaa" 但不可比對 "aa" 及 "aaaaa"
[xyz] 比對中括弧內的任一個字元 /[ecm]/ 可比對 "welcome" 中的 "e" 或 "c" 或 "m"
[^xyz] 比對不在中括弧內出現的任一個字元 /[^ecm]/ 可比對 "welcome" 中的 "w" "l" "o" 可見出其與 [xyz] 功能相反 同時請同學也注意 /^/ 與 [^] 之間功能的不同
[\b] 比對退位字元(Backspace character) 可以比對一個 backspace ,也請注意 [\b] 與 \b 之間的差別
\b 比對英文字的邊界,例如空格 例如 /\bn\w/ 可以比對 "noonday" 中的 'no' ;
/\wy\b/ 可比對 "possibly yesterday." 中的 'ly'
\B 比對非「英文字的邊界」 例如, /\w\Bn/ 可以比對 "noonday" 中的 'on' ,
另外 /y\B\w/ 可以比對 "possibly yesterday." 中的 'ye'
\cX 比對控制字元(Control character),其中 X 是一個控制字元 /\cM/ 可以比對 一個字串中的 control-M
\d 比對任一個數字,等效於 [0-9] /[\d]/ 可比對 由 "0" 至 "9" 的任一數字 但其餘如字母等就不可比對
\D 比對任一個非數字,等效於 [^0-9] /[\D]/ 可比對 "w" "a"... 但不可比對如 "7" "1" 等數字
\f 比對 form-feed 若是在文字中有發生 "換頁" 的行為 則可以比對成功
\n 比對換行符號 若是在文字中有發生 "換行" 的行為 則可以比對成功
\r 比對 carriage return
\s 比對任一個空白字元(White space character),等效於 [ \f\n\r\t\v] /\s\w*/ 可比對 "A b" 中的 "b"
\S 比對任一個非空白字元,等效於 [^ \f\n\r\t\v] /\S/\w* 可比對 "A b" 中的 "A"
\t 比對定位字元(Tab)
\v 比對垂直定位字元(Vertical tab)
\w 比對數字字母字元(Alphanumerical characters)或底線字母("_"),等效於 [A-Za-z0-9_] /\w/ 可比對 ".A _!9" 中的 "A" "_" "9"
\W 比對非「數字字母字元或底線字母」,等效於 [^A-Za-z0-9_] /\W/ 可比對 ".A _!9" 中的 "." " " "!" 可見出其與 \w 功能恰好相反
\ooctal 比對八進位,其中octal是八進位數目 /\oocetal123/ 可比對 與 八進位的ASCII中 "123" 所相對應的字元值
\xhex 比對十六進位,其中hex是十六進位數目 /\xhex38/ 可比對 與 16進位的ASCII中 "38" 所相對應的字元

2.再來給幾個範例讓各位參考,應該比較能理解他的用法:

/********************** 正規表示法範例 *************************/
preg_match_all("|<[^>]+>(.*)</[^>]+>|U",
"<b>example: </b><div align=left>this is a test</div>",
$out, PREG_PATTERN_ORDER);

preg_match_all('/\*(.*)\*/sU', "/* 我是第一個註解 */ 我不是註解 /* 我是第二個註解 */", $out);
preg_match_all ("/([<]div[>])(.*)([<][\/]div[>])/", "<div>123</div><div>456</div>", $out);

請自行透過echo $out[0][1]、$out[0][2]去比較結果

3.最後我再給點建議,通常第二個參數subject要比對的字串內容,可以透過下列方式取得再來比對

$handle = fopen("http://learn-house.idv.tw", "rb");
while (!feof($handle)) {
$contents .= fread($handle, 8192);
}
fclose($handle);

2010年10 月 posted by admin in 程式&軟體 and have No Comments

Place your comment

Please fill your data and comment below.
名稱:
信箱:
網站:
您的評論: