简体   繁体   English

我可以使用phpQuery找到完全匹配的内容吗?

[英]Can I find exact match using phpQuery?

I made a script using phpQuery. 我使用phpQuery编写了一个脚本。 The script finds td's that contain a certain string: 该脚本查找包含特定字符串的td:

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

It worked good until now. 到现在为止效果很好。 Because one clubname is for example Austria Lustenau and the second club is Lustenau. 因为一个俱乐部名称是例如奥地利Lustenau,第二个俱乐部名称是Lustenau。 It will select both clubs, but it only should select Lustenau (the second result), so I need to find a td containing an exact match. 它将选择两个俱乐部,但仅应选择Lustenau(第二个结果),因此我需要找到一个包含完全匹配项的td。

I know that phpQuery are using jQuery selectors, but not all. 我知道phpQuery使用的是jQuery选择器,但不是全部。 Is there a way to find an exact match using phpQuery? 有没有一种方法可以使用phpQuery查找完全匹配?

Update: It is possible, see the answer from @ pguardiario 更新:有可能,请参阅@ pguardiario的答案


Original answer. 原始答案。 (at least an alternative): (至少是一种替代方法):

No, unfortunately it is not possible with phpQuery. 不,很不幸,phpQuery无法实现。 But it can be done easily with XPath . 但是使用XPath可以轻松完成。

Imagine you have to following HTML: 假设您必须遵循HTML:

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

Use the following code to find exact matches with DOMXPath: 使用以下代码查找与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;
}

However, if you really need a phpQuery solution, use something like this: 但是,如果您确实需要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/>';
}

I've no experience of phpQuery but the jQuery would be something like this : 我没有phpQuery的经验,但jQuery可能是这样的:

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

The phpQuery documentation indicates that ->map() is available and that it accepts a callback function in the same way as in jQuery. phpQuery文档指示->map()可用,并且它以与jQuery中相同的方式接受回调函数。

I'm sure you will be able to perform the translation into phpQuery. 我相信您将能够执行到phpQuery的翻译。

Edit 编辑

Here's my attempt based on 5 minutes' reading - probably rubbish but here goes : 这是我根据5分钟的阅读时间做出的尝试-可能是垃圾,但这是:

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

Edit 2 编辑2

Here's a demo of the jQuery version . 这是jQuery版本演示

If phpQuery does what it says in its documentation , then (correctly translated from javascript) it should match the required element in the same way. 如果phpQuery做到了其文档中所说的内容 ,那么(正确翻译为javascript)它应该以相同的方式匹配所需的元素。

Edit 3 编辑3

After some more reading about the phpQuery callback system , the following code stands a better chance of workng : 在对phpQuery回调系统有更多了解之后,下面的代码更容易实现工作:

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

Note that ->map() is preferred over ->filter() as ->map() supports a simpler way to define pararameter "places" (see Example 2 in the referenced page). 请注意, ->map()优于->filter()因为->map()支持更简单的方法来定义参数“位置”(请参见参考页中的示例2)。

It can be done with filter, but it's not pretty: 可以使用过滤器来完成,但这并不漂亮:

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

But then, neither is switching back and forth between css and xpath 但是然后,两者都不会在css和xpath之间来回切换

I know this question is old, but I've written a function based on answer from hek2mgl 我知道这个问题很旧,但是我已经根据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;

}

?>

Usage 用法

<?php

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

?>

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

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