首先,我知道这是一个不好的做法,我已经回答了很多问题,但是为了澄清我被迫使用正则表达式,因为这个应用程序将正则表达式存储在数据库中并且只能以这种方式运行。我绝对无法改变功能
现在我们已经解决了这个问题..因为我总是使用DOM方法,我不习惯用正则表达式做这个。
我想要捕获介绍内容分区内的所有内容,直到第一个结束div标记。我不在乎正则表达式是否会在嵌套的div上失败。我也需要捕获空格(换行符)字符。
<div class="intro-content">
<p>blah</p>
<br/>
<strong>test</strong>
</div>
到目前为止的正则表达式:
<div\s*class="intro-content">(.*)</div>
这显然不起作用,因为.
字符与空格字符不匹配。
我确实已经发现有数百个问题,但我访问的问题只有相对简单的答案(不包括DOM建议答案),其中(.*)
是不够的,因为它没有考虑换行符,有些正则表达式太贪心了。
我不是在寻找能够解决所有可能性的完美,干净的解决方案(甚至可能) - 我只是想要一个适用于此解决方案的快速解决方案,以便我可以继续前进并开发更现代的应用程序没有那么可怕的编码。
答案 0 :(得分:5)
听起来你需要启用“dot all”(s)标志。这将使。匹配所有字符,包括换行符。例如:
preg_match('/<div\s*class="intro-content">(.*)<\/div>/s', $html);
答案 1 :(得分:2)
你应该不使用regexp来解析这样的html。 div
标签可以嵌套,因为正则表达式没有任何上下文,所以无法解析它。请改用HTML解析器。例如:
$doc = new DomDocument();
$doc->loadHtml($html);
foreach ($doc->getElementsByClassName("div") as $div) {
var_dump($div);
}
请参阅:DomDocument
修改强>
然后我看到了你的笔记:
我被迫使用正则表达式,因为此应用程序将正则表达式存储在数据库中,并且只能以这种方式运行。我绝对无法改变功能
好。至少要确保您匹配non-greedy。这样,只要没有嵌套标签,它就会匹配正确:
preg_match('/<div\s*class="intro-content">(.*?)<\/div>/s', $html);
答案 2 :(得分:-2)
这显然不起作用,因为
.
字符与空格字符不匹配。
应该这样做,但如果没有,我们可以将它们添加到:
<div\s*class="intro-content">([ \t\r\n.]*)</div>
然后你需要让它变得懒惰,因此它会捕获到第一个 </div>
而不是最后一个的所有内容。我们通过添加问号来完成此操作:
<div\s*class="intro-content">([ \t\r\n.]*?)</div>
有。试一试。您也可以使用单个\t\r\n
替换[
和]
之间的空格字符(\s
)。