使用php中的xpath创建preg_match

问题描述 投票:2回答:2

我正在尝试使用php中的XPATH获取内容。

<div class='post-body entry-content' id='post-body-37'>
<div style="text-align: left;">
<div style="text-align: center;">
Hi
</div></div></div>

我正在使用下面的php代码来获取输出。

 $dom = new DOMDocument;
 libxml_use_internal_errors(true);
 $dom->loadHTML($html);
 $xpath = new DOMXPath($dom);
 $xpath->registerPhpFunctions('preg_match');
 $regex = 'post-(content|[a-z]+)';
 $items = $xpath->query("div[ php:functionString('preg_match', '$regex', @class) > 0]");
 dd($items);

它返回如下输出

DOMNodeList {#580 
+length: 0 
} 
php regex dom xpath domxpath
2个回答
2
投票
对于这样的简单任务-使具有div属性的class节点从post-开始并包含content,您应该使用常规的简单XPath查询:

$xp->query('//div[starts-with(@class,"post-") and contains(@class, "content")]');

这里,-//div-获取所有...的div-starts-with(@class,"post-")-具有以“ post-”开头的“ class”属性-and-和...-contains(@class, "content")-在class属性值中包含“内容”子字符串。

要使用php:functionString,需要注册php命名空间(使用$xpath->registerNamespace("php", "http://php.net/xpath");)和PHP functions(要使用$xp->registerPHPFunctions();来注册它们)。

对于复杂的场景,当您需要更深入地分析值时,您可能需要创建并注册自己的函数:

function example($attr) { return preg_match('/post-(content|[a-z]+)/i', $attr) > 0; }

然后在XPath中:

$divs = $xp->query("//div[php:functionString('example', @class)]");

[这里,functionString@class属性的字符串内容传递给example函数,而不是对象(与php:function相同)。

请参见IDEONE demo

function example($attr) { return preg_match('/post-(content|[a-z]+)/i', $attr) > 0; } $html = <<<HTML <body> <div class='post-body entry-content' id='post-body-37'> <div style="text-align: left;"> <div style="text-align: center;"> Hi </div></div></div> </body> HTML; $dom = new DOMDocument; $dom->loadHTML($html, LIBXML_HTML_NOIMPLIED|LIBXML_HTML_NODEFDTD); $xp = new DOMXPath($dom); $xp->registerNamespace("php", "http://php.net/xpath"); $xp->registerPHPFunctions('example'); $divs = $xp->query("//div[php:functionString('example', @class)]"); foreach ($divs as $div) { echo $div->nodeValue; }

另请参阅有关在Using PHP Functions in XPath Expressions的XPath中使用PhpFunctions的精彩文章。

3
投票
这里是一个工作版本,带有您在注释中获得的不同建议:

libxml_use_internal_errors(true); $dom = new DOMDocument; $dom->loadHTML($html); $xpath = new DOMXPath($dom); // you need to register the namespace "php" to make it available in the query $xpath->registerNamespace("php", "http://php.net/xpath"); $xpath->registerPhpFunctions('preg_match'); // add delimiters to your pattern $regex = '~post-(content|[a-z]+)~'; // search your node anywhere in the DOM tree with "//" $items = $xpath->query("//div[php:functionString('preg_match', '$regex', @class)>0]"); var_dump($items);

显然,这种模式是无用的,因为您可以通过可用的XPATH字符串函数(例如contains)获得相同的结果。
© www.soinside.com 2019 - 2024. All rights reserved.