为什么这种模式只匹配第一个和最后一个

时间:2012-06-14 22:29:41

标签: regex

干草堆:

<h2 >a&nbsp; &middot;&nbsp;&middot;&nbsp;&middot;
</h2>
<div class="indent">
aaaa
</div>
<h2 >b&nbsp; &middot;&nbsp;&middot;&nbsp;&middot;
</h2>
<div class="indent">
bbbb
</div>

我使用的模式:

#<h2[^>]*>(a|b)(?!</h2>)[\s\S]*</h2><div class="indent">((?!</div>)[\s\S]+)</div>#

此模式仅匹配第一个h2内容(例如a&nbsp; &middot;&nbsp;&middot;&nbsp;&middot;)和最后一个div中的内容(例如bbbb

但我希望它能匹配h2和div中的所有内容以制作一对一的地图(例如a&nbsp; &middot;&nbsp;&middot;&nbsp;&middot; =&gt; aaaab&nbsp; &middot;&nbsp;&middot;&nbsp;&middot; =&gt; {{1 }),我该怎么做?

1 个答案:

答案 0 :(得分:1)

[\s\S]*[\s\S]+是贪婪的,这意味着它们会匹配尽可能多的字符。请尝试将其更改为[\s\S]*?[\s\S]+?

使用当前的正则表达式,如果您将[\s\S]*放入捕获组,您会发现它与以下内容匹配:

&nbsp; &middot;&nbsp;&middot;&nbsp;&middot;
</h2>
<div class="indent">
aaaa
</div>
<h2 >b&nbsp; &middot;&nbsp;&middot;&nbsp;&middot;

在最后添加?会使这个变得懒惰,因此它不会尽可能地匹配,而是匹配尽可能少的字符,因此它会像您想要的那样停在第一个</h2>。同样的推理适用于你的正则表达式中的[\s\S]+

您的示例字符串看起来似乎也会失败,因为您的正则表达式中间有</h2><div...,但在示例文本中,结尾</h2>和{之间始终存在换行符{1}},您应该将此部分更改为<div>。最终结果:

</h2>\s*<div...

But don't parse HTML with regex!