3

我使用 phpQuery 制作了一个脚本。该脚本查找包含特定字符串的 td:

$match = $dom->find('td:contains("'.$clubname.'")');

到现在为止效果很好。因为一个俱乐部名称是例如奥地利 Lustenau,而第二个俱乐部名称是 Lustenau。它将选择两个俱乐部,但它应该只选择 Lustenau(第二个结果),所以我需要找到一个包含完全匹配的 td。

我知道 phpQuery 正在使用 jQuery 选择器,但不是全部。有没有办法使用 phpQuery 找到完全匹配?

4

4 回答 4

3

更新:有可能,请参阅@pguardiario 的答案


原始答案。(至少另一种选择):

不,不幸的是,使用 phpQuery 是不可能的。但可以使用XPath轻松完成。

想象一下,您必须遵循 HTML:

$html = <<<EOF
<html>
  <head><title>test</title></head>
  <body>
    <table>
      <tr>
        <td>Hello</td>
        <td>Hello World</td>
      </tr>
    </table>
  </body>
</html>
EOF;

使用以下代码查找与 DOMXPath 的完全匹配:

// create empty document 
$document = new DOMDocument();

// load html
$document->loadHTML($html);

// create xpath selector
$selector = new DOMXPath($document);

// selects all td node which's content is 'Hello'
$results = $selector->query('//td[text()="Hello"]');

// output the results 
foreach($results as $node) {
    $node->nodeValue . PHP_EOL;
}

但是,如果您真的需要 phpQuery 解决方案,请使用以下内容:

require_once 'phpQuery/phpQuery.php';

// the search string
$needle = 'Hello';

// create phpQuery document
$document = phpQuery::newDocument($html);

// get matches as you suggested
$matches = $document->find('td:contains("' . $needle . '")');

// empty array for final results
$results = array();

// iterate through matches and check if the search string
// is the same as the node value
foreach($matches as $node) {
    if($node->nodeValue === $needle) {
        // put to results
        $results []= $node;
    }
}

// output results
foreach($results as $result) {
    echo $node->nodeValue . '<br/>';
}
于 2013-03-31T22:01:04.200 回答
2

它可以用过滤器完成,但它并不漂亮:

$dom->find('td')->filter(function($i, $node){return 'foo' == $node->nodeValue;});

但是,两者都不是在 css 和 xpath 之间来回切换

于 2013-04-01T06:52:40.180 回答
1

我没有 phpQuery 的经验,但 jQuery 会是这样的:

var clubname = 'whatever';
var $match = $("td").map(function(index, domElement) {
    return ($(domElement).text() === clubname) ? domElement : null;
});

phpQuery 文档表明它->map()是可用的,并且它以与 jQuery 相同的方式接受回调函数。

我相信您将能够执行到 phpQuery 的翻译。

编辑

这是我基于 5 分钟阅读的尝试 - 可能是垃圾,但这里有:

$match = $dom->find("td")->map(function($index, $domElement) {
    return (pq($domElement)->text() == $clubname) ? $domElement : null;
});

编辑 2

这是jQuery 版本的演示

如果 phpQuery 按照其文档中所说的进行,那么(从 javascript 正确翻译)它应该以相同的方式匹配所需的元素。

编辑 3

在对phpQuery 回调系统进行了更多阅读之后,以下代码更有可能工作:

function textFilter($i, $el, $text) {
    return (pq($el)->text() == $text) ? $el : null;
}};
$match = $dom->find("td")->map('textFilter', new CallbackParam, new CallbackParam, $clubname);

请注意,->map()它优于->filter()支持->map()更简单的方法来定义参数“位置”(参见参考页面中的示例 2)。

于 2013-03-31T21:48:15.903 回答
1

我知道这个问题很老,但我已经根据hek2mgl的回答编写了一个函数

<?php

// phpQuery contains function

/**
* phpQuery contains method, this will be able to locate nodes
* relative to the NEEDLE
* @param string element_pattern
* @param string needle
* @return array
*/
function contains($element_pattern, $needle) {

    $needle = (string) $needle;
    $needle = trim($needle);

    $element_haystack_pattern = "{$element_pattern}:contains({$needle})";
    $element_haystack_pattern = (string) $element_haystack_pattern;

    $findResults = $this->find($element_haystack_pattern);

    $possibleResults = array();

    if($findResults && !empty($findResults)) {
        foreach($findResults as $nodeIndex => $node) {
            if($node->nodeValue !== $needle) {
                continue;
            }
            $possibleResults[$nodeIndex] = $node;
        }
    }

    return $possibleResults;

}

?>

用法

<?php

$nodes = $document->contains("td.myClass", $clubname);

?>
于 2018-03-08T09:26:37.823 回答