繁体   English   中英

PHP Regex preg_match_all div ID不相同

[英]PHP Regex preg_match_all div not same id

我有一个这样的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 ">内容<div class="list-news fl pt10 alternative">我可以使用str_replace删除alternative类,但是如果不替换这个字符串,如何获取每个div匹配类list-news fl pt10.*?所有内容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不在乎单词边界和类顺序,而regex模式不在乎html代码可能存在的不规则性。

模式不起作用的原因是您无法获得重叠的匹配项。 由于第一次出现的结尾是<div class="list-news... ,所以下一次出现的开头不能是已经匹配的<div class="list-news...

可以将最后一个<div class="list-news...放到预先行中(?=...) (这只是一个检查,并且内容不属于匹配结果的一部分),但是,使用结束标记</div>更为简单。

\\K用于从匹配结果中删除之前(左侧)所有已匹配的内容。

一个不错的折衷方法是提取所有包含class属性的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);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM