我有一个像这样的html页面
<!DOCTYPE html>
<html>
....
<body>
<div class="list-news fl pt10 ">
Blue
</div>
<div class="list-news fl pt10 alternative">
Yellow
</div>
<div class="list-news fl pt10 ">
Red
</div>
<div class="list-news fl pt10 alternative">
Cyan
</div>
<div class="list-news fl pt10 ">
Black
</div>
<div class="list-news fl pt10 alternative">
White
</div>
</body>
</html>
现在我将编写一个排序 php 代码来获取我需要的所有内容
preg_match_all('@<div class="list-news fl pt10 .*?">(.*?)<div class="list-news fl pt10 .*?">@s',$rs,$match);
现在这就是结果
[1] => Array
(
[0] => <div>Blue</div></div>
[1] => <div>Red</div></div>
[2] => <div>Black</div></div>
)
结果只显示div <div class="list-news fl pt10 ">
中的内容并且无法获取 <div class="list-news fl pt10 alternative">
中的内容我可以使用 str_replace 删除 alternative
class 但如果不替换这个字符串,如何获取每个 div 匹配类中的所有内容 list-news fl pt10.*?
?
谢谢你的想法。
最佳答案
一个DOM方法(天真的contains
):
$dom = new DOMDocument();
@$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
$query = <<<'EOD'
//div[
contains(@class, 'list-news') and
contains(@class, 'fl') and
contains(@class, 'pt10')]
EOD;
$nodes = $xpath->query($query);
$results = array();
foreach ($nodes as $node) {
$results[] = trim($node->textContent);
}
print_r($results);
正则表达式方法(使用朴素模式):
preg_match_all('~<div class="list-news fl pt10\b[^>]+>\s*\K.*?(?=\s*</div>)~',
$html, $matches);
print_r($matches[0]);
这两种方法有点天真,因为 contains
不关心单词边界和类顺序,并且正则表达式模式也不关心 html 代码可能存在的不规则性。
您的模式不起作用的原因是您无法获得重叠匹配。由于第一次出现以 <div class="list-news...
结尾,下一次出现不能以相同的 <div class="list-news...
开头已经匹配过了。
把最后一个<div class="list-news...
展望 future (?=...)
(这只是一个检查,内容不是匹配结果的一部分)可以是一种方式。然而,使用结束标签 </div>
更简单。 .
\K
用于从匹配结果中删除(左侧)之前匹配的所有内容。
一个好的折衷方案是提取包含类属性的所有 div 标签,然后在提取和修剪文本内容之前使用正则表达式检查属性值是否确实是您想要的:
$dom = new DOMDocument();
@$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
$query = '//div[@class]';
$nodes = $xpath->query($query);
$results = array();
foreach($nodes as $node) {
if ( preg_match('~(?:\s|^)list-news\s+fl\s+pt10(?:\s|$)~',
$node->getAttribute('class')) )
$results = trim($node->textContent);
}
或没有 XPath :
$dom = new DOMDocument();
@$dom->loadHTML($html);
$divs = $dom->getElementsByTagName('div');
$results = array();
foreach($divs as $node) {
if ( $node->hasAttribute('class') &&
preg_match('~(?:\s|^)list-news\s+fl\s+pt10(?:\s|$)~',
$node->getAttribute('class')) )
$results = trim($node->textContent);
}
关于PHP 正则表达式 preg_match_all div 不相同 id,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24275598/