我知道也不推荐使用正则表达式来解析html,但这个问题更像是帮助理解正则表达式,而不是用它来解析html。
所以我有一个示例字符串(单行没有任何换行符或换行符):
<tr><th> H1<th>H2 <th> H3 <tr><td> R1C1<td>R1C2 <td> R1C3 <tr><td> R2C1<td>R2C2 <td> R2C3 <tr><td> R3C1<td>R3C2 <td> R3C3 < ..
为了更好地理解,有3行和3个单元格,结尾是未知标签,但没有TR或TD:
<tr><th> H1<th>H2 <th> H3
<tr><td> R1C1<td>R1C2 <td> R1C3
<tr><td> R2C1<td>R2C2 <td> R2C3
<tr><td> R3C1<td>R3C2 <td> R3C3
< ..
首先尝试我只想获得所有行,这是我对预期结果的看法:
<tr>
<
开头,其后跟随零或更多字符,但不是td
或th
我尝试过'基础',看看它是如何运作的。
(<tr>.*?)
为什么只获取<tr>
个字符串,而不是TR到TR?(<tr>.*?<tr)
,为什么只获得第1行和第3行? (<tr>.*?<(?!(td)|(th)))
..但我不确定这是否合适,而且这只返回第1行和第3行。
这是我尝试过的DEMO。
答案 0 :(得分:0)
模式是:
(<tr>.*?(?=<tr))
现在回答前两个问题。
问题1 :使用模式(<tr>.*?)
为什么只获取<tr>
个字符串,而不是TR到TR?
因为使用*?
,您要求使用惰性运算符。由于它是懒惰的,它会尝试尽可能匹配较少的字符。由于0个字符符合模式,因此会停止为0。
问题2 :使用模式(<tr>.*?<tr)
,为什么只获得第1行和第3行?
因为当您获得第一个匹配时,解析器的光标已经通过第二个<tr
传递。在第二场比赛中,它不会返回,因为第二场<tr
是第一场比赛的一部分。
使用先行((?=<tr)
),解析器不会在第一个匹配中使用第二个<tr
。你的最后一个模式几乎是好的,但即便如此,第一个TR#标记的<
在第一个匹配中被消耗,因此它不能成为第二个匹配的一部分。