好的开始我知道我不应该使用Regex来解析HTML,因为它不是非常可靠,不是100%安全等等。但是,这只是正则表达式的学习练习,与其他任何东西一样。
所以我的例子使用了英国广播公司网站http://www.bbc.co.uk/sport/football/premier-league/table。
该项目正在解析第一个表的tbody。我正在尝试进行搜索,以便仅返回与搜索值匹配的元素。例如,给定搜索“manc”我想要曼彻斯特城市和曼彻斯特联合的tr标签(从网址匹配)。
到目前为止我所拥有的是<tr\b[^>]*>(.*?)manc(.*?)</tr>
但是这个匹配从man city之后的第一个tr到结束tr然后返回man utd的预期结果。任何人都可以指出这个正则表达式出了问题。
编辑:来源(修剪)
<tbody id="trc-20-118996114-3">
<tr id="team-138824012" class="team first">
<td class="statistics"></td>
<td class='position'>
<span class='moving-up'>Moving up</span>
<span class='position-number'>1</span>
</td>
<td class="team-name">
<a href='http://www.bbc.co.uk/sport/football/teams/arsenal'>Arsenal</a>
</td>
<td class="played">0</td>
<td class="home-won">
<span>0</span>
</td>
<td class="home-drawn">0</td>
<td class="home-lost">0</td>
<td class="home-for">0</td>
<td class="home-against">0</td>
<td class="away-won">
<span>0</span>
</td>
<td class="away-drawn">0</td>
<td class="away-lost">0</td>
<td class="away-for">0</td>
<td class="away-against">0</td>
<td class="goal-difference">0</td>
<td class="points">0</td>
<td class="last-10-games">
<ol>
<li class="win" title="Win">
<span>Win</span>
</li>
<li class="draw" title="Draw">
<span>Draw</span>
</li>
<li class="draw" title="Draw">
<span>Draw</span>
</li>
<li class="draw" title="Draw">
<span>Draw</span>
</li>
<li class="loss" title="Loss">
<span>Loss</span>
</li>
<li class="win" title="Win">
<span>Win</span>
</li>
<li class="win" title="Win">
<span>Win</span>
</li>
<li class="loss" title="Loss">
<span>Loss</span>
</li>
<li class="win" title="Win">
<span>Win</span>
</li>
<li class="win last" title="Win">
<span>Win</span>
</li>
</ol>
</td>
<td class="status">
<a class="report" href="http://www.bbc.co.uk/sport/0/football/17973141">Report</a>
</td>
</tr>
<tr id="team-137316633" class="team">
<td class="statistics"></td>
<td class='position'>
<span class='moving-up'>Moving up</span>
<span class='position-number'>2</span>
</td>
<td class="team-name">
<a href='http://www.bbc.co.uk/sport/football/teams/aston-villa'>Aston Villa</a>
</td>
<td class="played">0</td>
<td class="home-won">
<span>0</span>
</td>
<td class="home-drawn">0</td>
<td class="home-lost">0</td>
<td class="home-for">0</td>
<td class="home-against">0</td>
<td class="away-won">
<span>0</span>
</td>
<td class="away-drawn">0</td>
<td class="away-lost">0</td>
<td class="away-for">0</td>
<td class="away-against">0</td>
<td class="goal-difference">0</td>
<td class="points">0</td>
<td class="last-10-games">
<ol>
<li class="loss" title="Loss">
<span>Loss</span>
</li>
<li class="draw" title="Draw">
<span>Draw</span>
</li>
<li class="draw" title="Draw">
<span>Draw</span>
</li>
<li class="loss" title="Loss">
<span>Loss</span>
</li>
<li class="draw" title="Draw">
<span>Draw</span>
</li>
<li class="loss" title="Loss">
<span>Loss</span>
</li>
<li class="draw" title="Draw">
<span>Draw</span>
</li>
<li class="draw" title="Draw">
<span>Draw</span>
</li>
<li class="loss" title="Loss">
<span>Loss</span>
</li>
<li class="loss last" title="Loss">
<span>Loss</span>
</li>
</ol>
</td>
<td class="status">
<a class="report" href="http://www.bbc.co.uk/sport/0/football/17973120">Report</a>
</td>
</tr>
<tr id="team-137318151" class="team">
<td class="statistics"></td>
<td class='position'>
<span class='moving-down'>Moving down</span>
<span class='position-number'>7</span>
</td>
<td class="team-name">
<a href='http://www.bbc.co.uk/sport/football/teams/manchester-city'>Man City</a>
</td>
<td class="played">0</td>
<td class="home-won">
<span>0</span>
</td>
<td class="home-drawn">0</td>
<td class="home-lost">0</td>
<td class="home-for">0</td>
<td class="home-against">0</td>
<td class="away-won">
<span>0</span>
</td>
<td class="away-drawn">0</td>
<td class="away-lost">0</td>
<td class="away-for">0</td>
<td class="away-against">0</td>
<td class="goal-difference">0</td>
<td class="points">0</td>
<td class="last-10-games">
<ol>
<li class="win" title="Win">
<span>Win</span>
</li>
<li class="win" title="Win">
<span>Win</span>
</li>
<li class="win" title="Win">
<span>Win</span>
</li>
<li class="win" title="Win">
<span>Win</span>
</li>
<li class="win" title="Win">
<span>Win</span>
</li>
<li class="win" title="Win">
<span>Win</span>
</li>
<li class="loss" title="Loss">
<span>Loss</span>
</li>
<li class="draw" title="Draw">
<span>Draw</span>
</li>
<li class="draw" title="Draw">
<span>Draw</span>
</li>
<li class="win last" title="Win">
<span>Win</span>
</li>
</ol>
</td>
<td class="status">
<a class="report" href="http://www.bbc.co.uk/sport/0/football/17973148">Report</a>
</td>
</tr>
<tr id="team-137318152" class="team">
<td class="statistics"></td>
<td class='position'>
<span class='moving-down'>Moving down</span>
<span class='position-number'>8</span>
</td>
<td class="team-name">
<a href='http://www.bbc.co.uk/sport/football/teams/manchester-united'>Man Utd</a>
</td>
<td class="played">0</td>
<td class="home-won">
<span>0</span>
</td>
<td class="home-drawn">0</td>
<td class="home-lost">0</td>
<td class="home-for">0</td>
<td class="home-against">0</td>
<td class="away-won">
<span>0</span>
</td>
<td class="away-drawn">0</td>
<td class="away-lost">0</td>
<td class="away-for">0</td>
<td class="away-against">0</td>
<td class="goal-difference">0</td>
<td class="points">0</td>
<td class="last-10-games">
<ol>
<li class="win" title="Win">
<span>Win</span>
</li>
<li class="win" title="Win">
<span>Win</span>
</li>
<li class="loss" title="Loss">
<span>Loss</span>
</li>
<li class="draw" title="Draw">
<span>Draw</span>
</li>
<li class="win" title="Win">
<span>Win</span>
</li>
<li class="loss" title="Loss">
<span>Loss</span>
</li>
<li class="win" title="Win">
<span>Win</span>
</li>
<li class="win" title="Win">
<span>Win</span>
</li>
<li class="win" title="Win">
<span>Win</span>
</li>
<li class="win last" title="Win">
<span>Win</span>
</li>
</ol>
</td>
<td class="status">
<a class="report" href="http://www.bbc.co.uk/sport/0/football/17973162">Report</a>
</td>
</tr>
</tbody>
答案 0 :(得分:0)
REGEX不适合这个,因为它不是一个解析器。除非情况非常宽容,特别是在JavaScript(具有相当原始的REGEX实现)中,否则无法确定哪些开放标记与哪些结束标记匹配。
首先,我们需要使用[\s\S]
而不是.
,因为后者不能用于多行,因为它与空白字符不匹配,并且您提到的表的HTML是多行。前者将是,因为它是一个与空间和非空间一切相匹配的范围 - 即一切都是。
考虑到这一点,你可能会想要这样做:
/<tr\b[^>]*?>[\s\S]*?manc[\s\S]*?<\/tr>/gi
...即。获取所有提及字符串'manc'的行。
采用以下简化的HTML:
<table>
<tr>
<td>Notts County</td>
</tr>
<tr>
<td>Manchester United</td>
</tr>
<tr>
<td>Arsenal</td>
</tr>
</table>
......上述模式将匹配
<tr>
<td>Notts County</td>
</tr>
<tr>
<td>Manchester United</td>
</tr>
这是合乎逻辑的。 REGEX模式从头开始,找到开头tr
(Notts County),并询问是否在找到不确定数量的可选字符后,找到字符串“Manc”。它是。
问题当然是,在找到“Manc”时,它已经无意中在tr
边界上徘徊到下一行,因为我们的[\s\S]*?
模式允许它。
我们无法阻止这种情况,因为REGEX不允许你否定序列 - 只有一个范围内的字符(负面预测和后面断言除外)。
简而言之,无论如何都要学习REGEX,但是你选择了一个困难的字符串:)
答案 1 :(得分:0)
问题是,你的正则表达式过于宽泛。看看你的要求:
<tr\b[^>]*>(.*?)manc(.*?)</tr>
让我们稍微简化一下。
<tr>.*?manc.*?</tr>
所以你说,好的。我需要匹配一个tr,接着是任何然后是manc然后是ANYTHING然后是一个结束tr。所以。当然会发生什么是正则表达式从第一个tr开始并且正常。我有一个tr让我保持匹配,直到我找到manc。与此同时,你可能只是传递了一堆其他 tr。但你的正则表达并不在乎。
试试这个:
<tr>(?:(?!</tr>).)*manc.+?</tr>
或者,我想在你的例子中:
<tr\b[^>]*>(?:(?!</tr>).)*manc.+?</tr>