使用 DOMDocument 在文本中注入 <customTag>

Inject <customTag> within text using DOMDocument

我想使用 DOMDocument 在文本节点的特定部分添加自定义标签,我的问题是我不知道如何找到该特定部分,例如:

"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."

我的目的是通过这种方式在某处添加标签:

"Lorem ipsum dolor sit amet, <emphasis>consectetur adipiscing</emphasis> elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."

问题是每个文本节点都是 DOMNode 的一个实例,所以我无法正确获取节点的文本内容和 "inject" 标签。 有什么建议么?谢谢

你想要这样的东西吗?一些逻辑和正则表达式,你就完成了。在评论中解释。

<?php
// example code
$string = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.';
$post = from("consectetur", "ut", $string, "<a>");

function from($from,$to, $string, $tag) {
    $frompost = strpos($string, $from); // get the pos of first string
    $topost = strpos($string, $to); // get the post of second string
    $substrfirst = substr($string, 0 , $frompost) . $tag; // trim string for the first word and add concatinate the tag
    $substrsecond = $substrfirst . substr($string, $frompost , strlen($from)); // trim another string starting from the first word and ending the length of the word and combine it with previous result
    $strinbetweenregex = '/(?<='.$from.')(.*)(?='.$to.')/'; // regex to get string in between
    preg_match($strinbetweenregex, $string, $matches); // get regex result
    $restString = substr($string, $topost + strlen($to) , strlen($string)); // get the rest of the string by starting from last str postition + the length of the last str to the length of the str 
    return $substrsecond.  $matches[0] . $to .$tag  . $restString; // return all the string.
}

这会给 Lorem ipsum dolor sit amet, <a>consectetur adipiscing elit, sed do eiusmod tempor incididunt ut</a> labore et dolore magna aliqua.
这也给了我们一个不平等。这是

$frompost < $topost

这也意味着您的第一个参数应该从左到右排在第一位,然后是第二个参数。

这个解决方案有点绕,但它基本上从 DOMNode(或 DOMElement)开始,最后将内容放回原来的变化。它还会尝试确保保留其周围的所有内容(包括标记和其他结构)。

想法是保存要更新的节点的 HTML,然后只需使用 str_replace() 来更改内容。然后将其导入回文档(使用 SimpleXML,因为我认为它更容易,然后将新节点导入 DOMDOcument,然后用新节点替换原始节点...

$source = '<div class="ToReplace">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</div>';

$textToTag="consectetur adipiscing";
$tag = "emphasis";

$doc = new DOMDocument();
$doc->loadHTML($source);

foreach ( $doc->getElementsByTagName("div") as $div )    {
    $nodeHTML = $doc->saveHTML($div);
    $newHTML = str_replace($textToTag, "<$tag>$textToTag</$tag>", $nodeHTML);
    $newNode = simplexml_load_string($newHTML);
    $import = $doc->importNode(dom_import_simplexml($newNode), true);
    $div->parentNode->replaceChild($import, $div);
}
echo $doc->saveHTML();