Pages

2014年12月23日 星期二


php貪婪與非貪婪比對

轉自
http://note.tc.edu.tw/868.html
https://disp.cc/b/11-2q1S

貪婪與非貪婪

當要抓取一段不固定的字串,例如 <b> 與 </b> 中間的字
最常看到的方法就是使用正規表示式 regular expression (以下簡稱 regex):

/<b>(.*?)<\/b>/



其中 . 代表任意字元
     * 代表前面的字元會出現0~∞次
     ? 代表使用非貪婪(non-greedy)的方法
     ( ) 代表將匹配的結果輸出到要抓取的第一個字串$1

若使用 /<b>(.*)<\/b>/ 則是代表使用貪婪(greedy)的方法

貪婪代表所有可能的匹配結果中,取字元數最多的
非貪婪就是取字元數最少的

如果整個字串確定就只有一組 <b> </b> 的話那匹配的結果就一樣
但若是像這樣的字串:

$string = "000<b>abc</b>1234<b>xxx</b>5678<b>yyy</b>0000";

貪婪抓到的       <----------------------------->
非貪婪抓到的     <->

可以看出使用非貪婪的方法才會抓到正確的結果
--------------------------------------------------------
在php preg_match中預設是採用貪婪比對,太貪婪反而不符合需要,因此得採用「非貪婪比對」,只要在modifier 中加上"U"即可,如下範例:

$str= "A running <b>dog</b> rams a walking <b>pig</b>.";

// Greedy matches ... default matches 貪婪比對,取出最大字串
$IsMatch= preg_match('/<b>(.*)<\/b>/', $str, $match);
if( $IsMatch ){
    print $match[1] . "\n" ;
}

// Nongreedy matches, use U modifier 非貪比對,取出最頭及最小字串
$IsMatch= preg_match('/<b>(.*)<\/b>/U', $str, $match);
if( $IsMatch ){
    print $match[1] . "\n" ;
}
執行結果:

dog</b> rams a walking <b>pig
dog

沒有留言:

張貼留言