preg_match_all 读取站点源多行和匹配项

preg_match_all reading sitesource multiple lines and matches

我用file_get_contents阅读我自己的网站来显示特定的文字。我显示采访的数据,我想获得采访标题和在另一个网站上使用的时间(link 到采访)。

相关代码块在table.

<td>
    Interview 1
    <small style="color:gray">
        Persons 2
        Cameras 2
    </small>
</td>
<td>
    1018 min
</td>

如您所见,Interview 1为标题,时间为1018。我自己尝试了这个,但不知何故模式有点疯狂。

preg_match_all('#<td>\s*(.+?)\s*<small style="color:gray">\s*<\/small>\s*<\/td><td>\s*(.+?)\s*<\/td>#is', $mysite, $match)

我使用 \s* 作为换行符和空格,并使用 (.+?) 来匹配。我的搜索模式有什么问题?

首先,您应该为此使用解析器,HTML 上的正则表达式正常运行。不过,您的正则表达式存在两个问题。

第一期:

<small style="color:gray">\s*<\/small>

该元素之间不只有白色 space。

问题二:

<\/td><td>

<td> 之间换行。

所以:

<td>\s*(.+?)\s*<small style="color:gray">.+?<\/small>\s*<\/td>\s<td>\s*(.+?)\s*<\/td>

应该适合你(对于这个静态示例)。如果 small 元素的内容是可选的,请将 + 更改为 *。另请注意,对于解析器,这些都不是问题。

这是一个使用 DOMDocument 的解决方案:

$doc = new DOMDocument();
$doc->loadHTML($html);
$xpath = new DOMXpath($doc);
foreach ($xpath->query('//td/small[@style="color:gray"]') as $small) {
    $td2 = $td = $small->parentNode;
    do $td2 = $td2->nextSibling; while($td2->nodeType != 1);
    $match[] = ["headline" => trim($td->firstChild->textContent), 
                "time" => trim($td2->textContent)];
}
print_r($match);

有效:

preg_match_all( '#<td>\s*(.*)\s*<small style="color:gray">.*</small>\s*</td>\s*<td>\s*(.*)\s*</td>#is', $mysite, $match);