简单 HTML DOM - 替换某个单词的所有出现 - 不影响属性
Simple HTML DOM - replace all occurrences of a certain word - without affecting attributes
我想知道:如何更改 HTML 中某个单词的所有出现,但仅限于标签之外?
示例:
假设我想用 <a href="#">myWordToReplace</a>
替换所有出现的 myWordToReplace
所以这个html
<p data-something="myWordToReplace"> myWordToReplace andSomeOtherText</p>
应该产生
<p data-something="myWordToReplace"> <a href="#">myWordToReplace</a> andSomeOtherText</p>
我试图用正则表达式实现这一点,但它也是一团糟 - 我想也许 DOM 解析器可以解决这个问题?
有什么帮助吗?
编辑: 如果您的所有文本都包含在某些标签中,@Muhammet 的回答将起到作用 - 但如果您的部分文本没有标签,则该文本将不会当然更换了。我现在也在努力实现这个目标。
示例:如果我想将 myWord
更改为 someOtherWord
:
Nam myWord pharetra <strong>auctor myWord</strong>
应该屈服
Nam someOtherWord pharetra <strong>auctor someOtherWord </strong>
但现在它只更改第二个词 - 强标签内的词。
你可以这样做
$html = file_get_html($file_url);
$content = $html->find('text');
foreach($content as $line) {
if(strpos($line->innertext, 'myWordToReplace') !== false) {
$line->innertext = str_replace('myWordToReplace','<a href="#">myWordToReplace</a>', $line->innertext);
}
}
这对我来说效果很好。不知道为什么不带"data-something",好像不喜欢两个词之间的破折号。但由于它有效,我希望它对你有用。
$my_html = '<p data="myWordToReplace"> myWordToReplace </p>';
$html = str_get_html($my_html);
foreach($html->find('p') as $p) {
if (!empty($p->data) && ($p->data == 'myWordToReplace')) {
$p->innertext = '<a href="#">'. $p->innertext .'</a>';
}
}
echo $html;
这是另一个基于DOM的解决方案,将部分文本节点包装到<a>
标签中(以search
为例):
$html = "<html><body>\n<!-- This is a comment for search //-->\n<span class=\"search\">New search performed</span></body></html>";
$key = "search";
$dom = new DOMDocument();
$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
$tt = $xpath->query('//text()');
foreach ($xpath->query('//text()') as $textNode) {
$fragment = $dom->createDocumentFragment();
$text = $textNode->nodeValue;
while (($pos = stripos($text, $key)) !== false) {
$fragment->appendChild(new DOMText(substr($text, 0, $pos)));
$word = substr($text, $pos, strlen($key));
$lnk = $dom->createElement('a');
$lnk->appendChild(new DOMText($word));
$lnk->setAttribute('href', '#');
$fragment->appendChild($lnk);
$text = substr($text, $pos + strlen($key));
}
if (!empty($text))
$fragment->appendChild(new DOMText($text));
$textNode->parentNode->replaceChild($fragment, $textNode);
}
echo $dom->saveHTML();
这是一个IDEONE demo
我想知道:如何更改 HTML 中某个单词的所有出现,但仅限于标签之外?
示例:
假设我想用 <a href="#">myWordToReplace</a>
myWordToReplace
所以这个html
<p data-something="myWordToReplace"> myWordToReplace andSomeOtherText</p>
应该产生
<p data-something="myWordToReplace"> <a href="#">myWordToReplace</a> andSomeOtherText</p>
我试图用正则表达式实现这一点,但它也是一团糟 - 我想也许 DOM 解析器可以解决这个问题? 有什么帮助吗?
编辑: 如果您的所有文本都包含在某些标签中,@Muhammet 的回答将起到作用 - 但如果您的部分文本没有标签,则该文本将不会当然更换了。我现在也在努力实现这个目标。
示例:如果我想将 myWord
更改为 someOtherWord
:
Nam myWord pharetra <strong>auctor myWord</strong>
应该屈服
Nam someOtherWord pharetra <strong>auctor someOtherWord </strong>
但现在它只更改第二个词 - 强标签内的词。
你可以这样做
$html = file_get_html($file_url);
$content = $html->find('text');
foreach($content as $line) {
if(strpos($line->innertext, 'myWordToReplace') !== false) {
$line->innertext = str_replace('myWordToReplace','<a href="#">myWordToReplace</a>', $line->innertext);
}
}
这对我来说效果很好。不知道为什么不带"data-something",好像不喜欢两个词之间的破折号。但由于它有效,我希望它对你有用。
$my_html = '<p data="myWordToReplace"> myWordToReplace </p>';
$html = str_get_html($my_html);
foreach($html->find('p') as $p) {
if (!empty($p->data) && ($p->data == 'myWordToReplace')) {
$p->innertext = '<a href="#">'. $p->innertext .'</a>';
}
}
echo $html;
这是另一个基于DOM的解决方案,将部分文本节点包装到<a>
标签中(以search
为例):
$html = "<html><body>\n<!-- This is a comment for search //-->\n<span class=\"search\">New search performed</span></body></html>";
$key = "search";
$dom = new DOMDocument();
$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
$tt = $xpath->query('//text()');
foreach ($xpath->query('//text()') as $textNode) {
$fragment = $dom->createDocumentFragment();
$text = $textNode->nodeValue;
while (($pos = stripos($text, $key)) !== false) {
$fragment->appendChild(new DOMText(substr($text, 0, $pos)));
$word = substr($text, $pos, strlen($key));
$lnk = $dom->createElement('a');
$lnk->appendChild(new DOMText($word));
$lnk->setAttribute('href', '#');
$fragment->appendChild($lnk);
$text = substr($text, $pos + strlen($key));
}
if (!empty($text))
$fragment->appendChild(new DOMText($text));
$textNode->parentNode->replaceChild($fragment, $textNode);
}
echo $dom->saveHTML();
这是一个IDEONE demo