作者DongFeng (Little Five)
看板PHP
標題Fw: [問題] 一段表達式, 希望版友能幫忙解析...
時間Mon Nov 4 22:13:05 2013
※ [本文轉錄自 RegExp 看板 #1ITwjeQ0 ]
作者: DongFeng (Little Five) 看板: RegExp
標題: Re: [問題] 一段表達式, 希望版友能幫忙解析...
時間: Mon Nov 4 22:12:52 2013
謝謝各位前輩的回答, 前陣子比較忙沒有時間上來回覆感謝各位
特別謝謝danny8376前輩, 謝謝您那麼用心回答還特地回信到我信箱>///<
經過danny前輩分階段的講解我已經知道這行表達式是怎麼運作的了
白話的說來就是匹配
<table此處可為非>的任意字串(含空白與無)>
匹配非<(一般來說是空白或無)
匹配非<table、非</table的任意tag(一般來說是<thead/><tbody/><tr/><td/></tfoot/>)
</table>
這整段可以找出頁面中所有不含table的table
但對於*+的部分我還是有點疑惑, 我自己的解讀是[^>]*+是匹配非>的任意字串後再以該
字串作一次以上的驗證,也就是說
<table c>
<table cl>
<table cla>
<table clas>
<table class>
<table class=>
<table class=">
......
<table class="test">
因為任意字元的關係所以匹配到c就停止並回傳成功, 不知道這樣解讀對不對
-----------------------------------------------------------------------------
後來在表達式的使用上我又遇到了其他的問題, 如前所述前面的表達式是匹配不含tabel
的tabel, 但在某些網頁上會遇到下面的狀況
<table>
<tr>
<td>
<table>...</table>
內文...
</td>
</tr>
</table>
使用同樣的表達式去匹配的話會抓出最裡頭的table但卻抓不出內文, 後來我在版上爬文
後用了另一段表達式: /<table[^>]*+>((<.+?>.*?<\/.+?>|.)+?)<\/table>/is
這段表達式可以完整的抓出最外層table以及內容(含裏table)
但後來我發現這段表達式只有抓出內文中的其中一個table, 雖然抓出來的table是我想要
的沒錯但就是疑惑為什麼其他的table沒被抓出來...
隨文附上資料來源:
http://www.thsrc.com.tw/tw/TimeTable/SearchResult
其實這是高鐵時刻表查詢系統, POST的所需資料後即可導出相應的時刻表
導出的時刻表內有兩個table, 分別是
<table>...</table>
<table class="word_size">...</table>
沒有抓出來的<table class="word_size">...</table>, 雖然裡頭只是無關緊要的資料,
但因為有寫[^>]*+的關係一直覺的應該會抓出來才對...
希望各位前輩能夠再撥空幫小的解答一下, 敘述能力不大好文長還請見諒...
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 175.111.59.235
※ 發信站: 批踢踢實業坊(ptt.cc)
※ 轉錄者: DongFeng (175.111.59.235), 時間: 11/04/2013 22:13:05
1F:→ s540421:用preg_match還是preg_match_all ? 11/05 10:40
2F:→ DongFeng:preg_match_all 11/05 11:07
3F:→ s540421:問題比較可能出在(<.+?>.*?<\/.+?>|.)+? 11/06 00:00
4F:→ s540421:檢測工具也只回報catastrophic backtracking 11/06 00:02
5F:→ s540421:猜是因為進入.*?,造成後面的文字都被吞掉,讓</table>無 11/06 00:13
6F:→ s540421:法匹配到 11/06 00:13
7F:→ s540421:打錯,是.+? 11/06 00:14
8F:→ s540421:搞錯了,+?是not greedy 11/06 00:20
9F:→ s540421:換猜catastrophic backtracking ... XD 11/06 00:28
10F:→ s540421:雖然兩種pattern的結果不一樣,不過第一種pattern在工具內 11/06 00:33
11F:→ s540421:要41366次match才能跑完全文,第二種pattern則無法計算 11/06 00:34
12F:→ s540421:給定更明確的匹配樣式應該會有不一樣的結果 11/06 00:36
13F:→ s540421:*+ Match 0 or more times and give nothing back 11/06 01:16
14F:→ s540421:這段是說*+會拿走所有批配到的字元,不做backtracking 11/06 01:16
15F:→ s540421:像用a*+ab去測aaab就會fail,因為全部的a都被a*+拿走了 11/06 01:19