如何匹配除两个标签之间的模式之外的任何内容

时间:2010-04-30 07:58:05

标签: php regex

我正在尝试匹配由HTML组成的字符串。基本上它是一个图像库,因此字符串中有很多相似之处。字符串中有很多<dl>个标签,但我希望匹配<dl>(.?)+</dl>之前的最后一个</div>组合。

我设计的方法是确保我匹配的<dl组合中没有任何<dl></dl>。我不在乎还有什么,包括其他标签和换行符。

我决定用正则表达式做这件事,因为我无法预测这个子字符串会有多长或者它内部的任何东西。

这是我当前的正则表达式,它只返回一个带有两个NULL指示的数组:

preg_match_all('/<dl((?!<dl).)+<\/dl>(?=<\/div>)/', $foo, $bar)

正如您所看到的,我使用否定前瞻来尝试查看此内容中是否还有另一个<dl>。我也在这里尝试了负面的观察,结果相同。我也尝试使用+?而不仅仅+无效。请注意,没有模式<dl><dl></dl>或其他任何模式,但我的正则表达式与第一个<dl>和最后一个</dl>匹配,或者根本不匹配。

现在我意识到.将不会与换行符相匹配,但我已经尝试了任何我能想到的东西,它仍然提供了我的NULL指示或几乎整个字符串(从第一次出现{ {1}}到<dl,其中包括</dl></div>的其他几个出现,正是我不想要的内容。老实说,我不知道我做错了什么。

感谢您的帮助!我花了一个多小时才试图解决这个问题,这就是让我把头发拉出来。

3 个答案:

答案 0 :(得分:2)

Don't use regular expressions for irregular languages like HTML。请改用parser。它会为您节省大量时间和pain

答案 1 :(得分:0)

我建议改用整洁。您可以轻松地将所有需要的标签与其内容相加,即使对于损坏的HTML也是如此。

一般情况下,我不建议使用正则表达式编写解析器。

请参阅http://www.php.net/tidy

答案 2 :(得分:0)

在我发布这个问题大约2分钟后,我发现它很疯狂,我发现了一种有效的方法。

preg_match_all('/<dl([^\z](?!<dl))+?<\/dl>(?=<\/div>)/', $foo, $bar);

[^\z]疯狂只是我用来说“匹配所有角色,甚至换行符”的一种方式