Php XPath包含()搜索精确匹配

Php XPath包含()搜索精确匹配,php,regex,xpath,Php,Regex,Xpath,是否可以使用fn:contains搜索DOMDocument对象,并仅在与单词完全匹配时返回true 我有一个不是自己编写的文本替换代码段,它对关键字进行内部链接替换。但在书面上,它也取代了部分单词,而不仅仅是完整的单词 以下是片段: $autolinks = $this->config->get('autolinks'); if (isset($autolinks) && (strpos($this->data['description'], 'iframe'

是否可以使用fn:contains搜索DOMDocument对象,并仅在与单词完全匹配时返回true

我有一个不是自己编写的文本替换代码段,它对关键字进行内部链接替换。但在书面上,它也取代了部分单词,而不仅仅是完整的单词

以下是片段:

$autolinks = $this->config->get('autolinks');
if (isset($autolinks) && (strpos($this->data['description'], 'iframe') == false) 
        && (strpos($this->data['description'], 'object') == false)):
    $xdescription = mb_convert_encoding(html_entity_decode($this->data['description'], ENT_COMPAT, "UTF-8"), 'HTML-ENTITIES', "UTF-8"); 
    libxml_use_internal_errors(true);
    $dom = new DOMDocument;             
    $dom->loadHTML('<div>'.$xdescription.'</div>');             
    libxml_use_internal_errors(false);
    $xpath = new DOMXPath($dom);
    foreach ($autolinks as $autolink):
        $keyword    = $autolink['keyword'];
        $xlink  = mb_convert_encoding(html_entity_decode($autolink['link'], ENT_COMPAT, "UTF-8"), 'HTML-ENTITIES', "UTF-8");
        $target     = $autolink['target'];
        $tooltip    = isset($autolink['tooltip']);                          
        $pTexts     = $xpath->query(
            sprintf('///text()[contains(., "%s")]', $keyword)
        );
        foreach ($pTexts as $pText):
            $this->parseText($pText, $keyword, $dom, $xlink, $target, $tooltip);
        endforeach;
    endforeach;
    $this->data['description'] = $dom->saveXML($dom->documentElement);
endif;
$autolinks=$this->config->get('autolinks');
if(isset($autolinks)&(strpos($this->data['description'],'iframe')==false)
&&(strpos($this->data['description'],'object')==false)):
$xdescription=mb_convert_编码(html_entity_decode($this->data['description'],ENT_COMPAT,“UTF-8”),'html-ENTITIES',“UTF-8”);
libxml\u使用\u内部错误(true);
$dom=新的DOMDocument;
$dom->loadHTML('.$XDDescription');
libxml\u使用\u内部错误(false);
$xpath=newdomxpath($dom);
foreach($autolinks作为$autolink):
$keyword=$autolink['keyword'];
$xlink=mb_convert_编码(html_实体_解码($autolink['link'],ENT_COMPAT,“UTF-8”),'html-ENTITIES',“UTF-8”);
$target=$autolink['target'];
$tooltip=isset($autolink['tooltip']);
$pTexts=$xpath->query(
sprintf('///text()[包含(,“%s”)]',$keyword)
);
外汇($pTexts作为$pText):
$this->parseText($pText、$keyword、$dom、$xlink、$target、$tooltip);
endforeach;
endforeach;
$this->data['description']=$dom->saveXML($dom->documentElement);
endif;
例如:


如果我的关键字是“按摩”*按摩*r部分匹配并转换为链接,则仅转换整个单词按摩,而不转换为按摩器。

您应该使用fn:matches而不是fn:contains。这允许您使用正则表达式进行匹配。然后可以将单词边界包含在\b中

sprintf('///text()[matches(., "\b%s\b")]', $keyword)
请注意,这不会影响函数parseText正在执行的任何操作。因此,虽然
这是一个包含“按摩器”一词的句子。
不会受到影响,但我不能保证
按摩器会给客户按摩。
。为了确保正确处理此问题,需要修改parsetext函数。可能以与上述类似的方式


还请注意,您可能需要对parsetext进行修改,这意味着不需要进行上述更改。

您应该使用fn:matches而不是fn:contains。这允许您使用正则表达式进行匹配。然后可以将单词边界包含在\b中

sprintf('///text()[matches(., "\b%s\b")]', $keyword)
请注意,这不会影响函数parseText正在执行的任何操作。因此,虽然
这是一个包含“按摩器”一词的句子。
不会受到影响,但我不能保证
按摩器会给客户按摩。
。为了确保正确处理此问题,需要修改parsetext函数。可能以与上述类似的方式


还要注意,您可能需要对parsetext进行修改,这意味着上述更改变得不必要。

XSLT 1.0中的文本操作非常有限,但是如果您不能移动到2.0(为什么不?),那么
translate()
通常会起到帮助作用。使用
translate()
将所有常用标点符号替换为空格,使用
concat()
前后添加空格,然后测试
包含(‘按摩’)
(注意空格)。

XSLT 1.0中的文本操作非常有限,但如果无法移动到2.0(为什么不?),则
translate()
经常来救援。使用
translate(),我刚刚在
$keyword
变量的末尾添加了一个空格,所以现在只有在找到整个单词时它才会返回true

foreach ($autolinks as $autolink):
    $keyword    = trim($autolink['keyword']) . ' ';
    $xlink      = mb_convert_encoding(html_entity_decode($autolink['link'], ENT_COMPAT, "UTF-8"), 'HTML-ENTITIES', "UTF-8");
    $target     = $autolink['target'];
    $tooltip    = isset($autolink['tooltip']);                          
    $pTexts     = $xpath->query(
        sprintf('///text()[contains(., "%s")]', $keyword)
    );
    foreach ($pTexts as $pText):
        $this->parseText($pText, $keyword, $dom, $xlink, $target, $tooltip);
    endforeach;
endforeach;

感谢所有试图提供帮助的人。

事实证明,这非常简单,我只是在
$keyword
变量的末尾添加了一个空格,所以现在只有在找到整个单词时它才会返回true

foreach ($autolinks as $autolink):
    $keyword    = trim($autolink['keyword']) . ' ';
    $xlink      = mb_convert_encoding(html_entity_decode($autolink['link'], ENT_COMPAT, "UTF-8"), 'HTML-ENTITIES', "UTF-8");
    $target     = $autolink['target'];
    $tooltip    = isset($autolink['tooltip']);                          
    $pTexts     = $xpath->query(
        sprintf('///text()[contains(., "%s")]', $keyword)
    );
    foreach ($pTexts as $pText):
        $this->parseText($pText, $keyword, $dom, $xlink, $target, $tooltip);
    endforeach;
endforeach;
感谢所有试图提供帮助的人。

如果不支持
匹配()
结束-with()
,您可以使用
开始-with()
字符串长度()

例如:

[starts-with(.,'$var') and string-length(.)=string-length('$var')]
这相当于
matches()

当不支持
matches()
end-with()
时,您可以使用
start-with()
string-length()
四处走动

例如:

[starts-with(.,'$var') and string-length(.)=string-length('$var')]

这相当于
matches()

示例xml将非常有用。您有哪些输入会产生不好的输出?您希望更改的输入是什么?对不起,我不明白您的要求。我需要知道如何仅在
$xpath->query(sprintf('///text()[contains(,“%s”)]',$keyword)中匹配整词上面的部分。正如我所说的,输入ie:
$keyword
变量将是“按摩”,错误的输出是单词“按摩器”仅链接到单词按摩上,而结尾“r”作为纯文本保持未链接。单词“massager”根本不应该匹配,因为它不是确切的关键字。将在xml节点中进行按摩这是一个包含单词massage的句子。是一场比赛吗?或者是表单消息上的所有匹配项是
$this->data['description']
是一个文本块,即产品描述。因此,是的
这是一个包含单词按摩的句子。
可能是匹配的,但目前也是
这是一个包含单词按摩的句子。
这是我想要消除的。示例xml会很有用。您有哪些输入会产生不好的输出?您需要的输入是什么