PHP 正则表达式 preg_match_all div 不相同 id

标签 php jquery html css regex

我有一个像这样的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/

相关文章:

html - Bootstrap - 多语言 2 方向支持的良好做法?

PHP Mongo - 查找集合中的最后一个对象

php - sfGuardDoctrine 插件和表单消息

php - js - 使用 jquery 设置 var = 元素的宽度

javascript - 为什么我的 jQuery .click() 回调没有正确处理输入?

javascript - 将鼠标悬停在缩略图上以启动新图像;悬停结束后新图像仍然存在

javascript - 粘性导航和 jQuery

html - 如何在部分背景中添加视频 iframe?

php - foreach 循环中的 while 循环不正确循环

php - 数组合并问题