(轉)PHP正則表達式匹配嵌套HTML標簽的方法和技巧


正則表達式是一個非常有用的編程技能。一般來說,簡單的抓取一個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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM