正則表達式是一個非常有用的編程技能。一般來說,簡單的抓取一個HTML頁面的某一條信息,比如<title>標題</title>,是很容易實現的。但是,我們往往要抓取某一個列表頁面里的多個重復的<div></div>塊里的特定內容,並且<div></div>塊還有嵌套的使用,我們抓取的則是每個重復<div></div>塊里的多個信息。同時,網頁源文件不同於一般的字符串,其還存在大量的回車、換行和制表符,這些都造成了匹配失敗。而初學者往往無法判斷到底是哪個環節出現了問題,並且看到高度技巧化的正則表達式會感到非常沮喪,從而導致放棄問題的解決。
經過筆者多日的研究,終於摸索出以下方法和技巧,歡迎大家交流指正。
請看如下注意點和步驟:
1.注意/一定要被轉義成\/,否則會報錯
preg_match_all() [function.preg-match-all]: Unknown modifier
2.正則表達式用單引號'和/作為開始和結束的標界,比如'/reg partten/',采用這樣的寫法,正則表達式里的雙引號"不必轉義
比如,
$partten='/<div class="goods_item"><a href="([^<>]+)" target="_blank"><img data-ks-lazyload="([^<>]+)" alt="([^<>]+)" width="" height=""\/>/';
3.需要先去除所有的換行符、制表符、回車等等,對於便於閱讀的html源文件由於上述符號的存在會造成無法匹配。
$str=preg_replace("/[\t\n\r]+/","",$str);
4.我們感興趣的匹配信息,通常是html元素中的屬性的值,因此要去除<>,否則只會匹配最后一條之前的全部信息。
比如,對於$string="<div><a href=“1.jpg”></a></div><div><a href=“2.jpg”></a></div><div><a href=“3.jpg”></a></div>",
$partten='/<div><a href=“(.+)”/';的匹配結果是:1.jpg”></a></div><div><a href=“2.jpg”></a></div><div><a href=“3.jpg”></a></div>
這是因為,上述給出的正則表達式確實沒有限定匹配的范圍只是第一個超鏈接<a href=“1.jpg”></a>。
因此,要想匹配上述三個超鏈接的 href屬性,需要將上述匹配限定在<a href=“1.jpg”>里面,方法也很簡單,將(.+)換成([^<>]+),即可。也就是說,這個匹配不包含下一個出現<>的地方,從而將匹配限定在同一個html標簽內
做到以上幾點,就可以完全無視html標簽嵌套不嵌套的問題,從而抓取到一個頁面所有的div重復塊中我們感興趣的內容,下附一例。
1 <? 2 //被匹配的html代碼 3 $html=' 4 <div class="goods"> 5 <a href="http://url1111" target="_blank"> 6 <img data-ks-lazyload="http://1111.jpg" alt="alt1111" width="" height=""/> 7 </a> 8 </div> 9 <div class="goods"> 10 <a href="http://url2222" target="_blank"> 11 <img data-ks-lazyload="http://2222.jpg" alt="alt2222" width="" height=""/> 12 </a> 13 </div> 14 <div class="goods"> 15 <a href="http://url3333" target="_blank"> 16 <img data-ks-lazyload="http://3333.jpg" alt="alt3333" width="" height=""/> 17 </a> 18 </div>'; 19 20 //去掉換行、制表等特殊字符,可以echo一下看看效果 21 $html=preg_replace("/[\t\n\r]+/","",$html); 22 23 //匹配表達式,注意兩點,一是包含在'/ /'里面,再就是/要做轉義處理成\/ 24 $partern='/<div class="goods"><a href="([^<>]+)" target="_blank"><img data-ks-lazyload="([^<>]+)" alt="([^<>]+)" width="" height=""\/><\/a><\/div>/'; 25 26 //匹配結果 27 preg_match_all($partern,$html,$result); 28 29 //打印結果 30 var_dump($result); 31 ?>
輸出結果,一共有4個子數組,第一個子數組是匹配到的所有的項,后面三個子數組是我們匹配表達式里的三個匹配項:
1 array(4) { 2 [0]=> 3 array(3) { 4 [0]=> 5 string(144) "<div class="goods"><a href="http://url1111" target="_blank"><img data-ks-lazyload="http://1111.jpg" alt="alt1111" width="" height=""/></a></div>" 6 [1]=> 7 string(144) "<div class="goods"><a href="http://url2222" target="_blank"><img data-ks-lazyload="http://2222.jpg" alt="alt2222" width="" height=""/></a></div>" 8 [2]=> 9 string(144) "<div class="goods"><a href="http://url3333" target="_blank"><img data-ks-lazyload="http://3333.jpg" alt="alt3333" width="" height=""/></a></div>" 10 } 11 [1]=> 12 array(3) { 13 [0]=> 14 string(14) "http://url1111" 15 [1]=> 16 string(14) "http://url2222" 17 [2]=> 18 string(14) "http://url3333" 19 } 20 [2]=> 21 array(3) { 22 [0]=> 23 string(15) "http://1111.jpg" 24 [1]=> 25 string(15) "http://2222.jpg" 26 [2]=> 27 string(15) "http://3333.jpg" 28 } 29 [3]=> 30 array(3) { 31 [0]=> 32 string(7) "alt1111" 33 [1]=> 34 string(7) "alt2222" 35 [2]=> 36 string(7) "alt3333" 37 } 38 }
原文:http://blog.csdn.net/donglynn/article/details/35788879
