作者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