在下面的foreach循环中,为了仅返回关键字的第一个实例,将其包装为粗体标记,然后退出循环和函数,正确的语法是什么?
例如,关键字是“蓝色小部件”。所以我希望字符串的第一次出现(在$ content中)从蓝色小部件更改为
<b>blue widgets</b>
这是我用来解析内容的例程......
function sx_decorate_keyword($content){
$keyword = "blue widgets";
$d = new DOMDocument();
$d->loadHTML($content);
$x = new DOMXpath($d);
foreach($x->query("//text()[
contains(.,$keyword')
and not(ancestor::h1)
and not(ancestor::h2)
and not(ancestor::h3)
and not(ancestor::h4)
and not(ancestor::h5)
and not(ancestor::h6)]") as $node){
//need to wrap bold tags around the first instance of the keyword, then exit the routine
}
return $content;
}
答案 0 :(得分:2)
正如Dmitri所说,只是在第一个文本节点上工作。下面的示例采用剖析包含您的关键字的DOMText节点并将第一个匹配包装在<b>
元素中的方法。
$nodes = $x->query("... your xpath ...");
if ($nodes && $nodes->length) {
$node = $nodes->item(0);
// Split just before the keyword
$keynode = $node->splitText(strpos($node->textContent, $keyword));
// Split after the keyword
$node->nextSibling->splitText(strlen($keyword));
// Replace keyword with <b>keyword</b>
$replacement = $d->createElement('b', $keynode->textContent);
$keynode->parentNode->replaceChild($replacement, $keynode);
}
参考:
DOMNodeList
- 来自DOMXPath::query()
DOMText::splitText()
- 将此节点分解为指定偏移量的两个节点DOMNode::replaceChild()
- 取代孩子答案 1 :(得分:0)
您可以使用 break;
突破循环或者你不能使用foreach而只是只使用第一个元素。
$Matches = $x->query("//text()[
contains(.,$keyword')
and not(ancestor::h1)
and not(ancestor::h2)
and not(ancestor::h3)
and not(ancestor::h4)
and not(ancestor::h5)
and not(ancestor::h6)]");
if($Matches && $Matches->length > 0){
$myText = $Matches->item(0);
// now do you thing with $myText like create <b> element, append $myText as child,
// replaceNode $myText with new <b> node
}
不确定这是否有效,但是那样......