gpt4 book ai didi

php - PHP 中的 Walking Dom 将找到的字符串列表替换为 "HTML text"

转载 作者:搜寻专家 更新时间:2023-10-31 22:07:27 24 4
gpt4 key购买 nike

我想将链接列表(数组中的 hrefs)中的单词列表(数组中)替换为 html 页面。

我认为主要有 2 个选择:

  1. 通过正则表达式执行此操作(强烈建议不要解析和更改 html)。

  2. 使用 html 解析器并遍历 DOM 以替换每个单词和链接列表。

第二个选项的问题如下:

  1. 我不想替换之前在 html 页面中创建的链接,我必须知道在标签所在的列表中找到的每个单词。

  2. 我不想替换 DOM 每个节点上的单词,只替换没有子节点的节点,即只替换叶子中的节点。

简单示例:

$aURLlist = array('www.google.com','www.facebook.com');
$aWordList = array('Google', 'Facebook');
$htmlContent='<html><body><div>Google Inc. is an American multinational corporation specializing in Internet-related services and products.</div><div>Facebook is an online social networking service, whose name stems from the colloquial name for the book given to students at the start of the academic year by some university administrations in the United States to help students get to know each other.</div></body></html>';
$dom = new DOMDocument();
$dom->loadHTML($htmlContent);
$htmlContent=walkingDom($dom,$aURLlist,$aWordList); //replace all words of $aWordList found in text nodes of $dom TO links with href equal to URL in $aURLlist

结果:

$htmlContent=<html><body><div><a href='www.google.com'>Google</a> Inc. is an American multinational corporation specializing in Internet-related services and products.</div><div><a href='www.facebook.com'>Facebook</a> is an online social networking service, whose name stems from the colloquial name for the book given to students at the start of the academic year by some university administrations in the United States to help students get to know each other.</div></body></html>';

我有一个使用 DOMDocument 库遍历 DOM 的递归函数,但我无法附加“ anchor ”节点来替换在叶“文本”节点中找到的单词。

function walkDom($dom, $node, $element, $sRel, $sTarget, $iSearchLinks, $iQuantityTopics, $level = 0, $bLink = false) {
$indent = '';
if ($node->nodeName == 'a') {
$bLink = true;
}
for ($i = 0; $i < $level; $i++)
$indent .= '&nbsp;&nbsp;';
if ($node->nodeType != XML_TEXT_NODE) {
//echo $indent . '<b>' . $node->nodeName . '</b>';
//echo $indent . '<b>' . $node->nodeValue . '</b>';

if ($node->nodeType == XML_ELEMENT_NODE) {
$attributes = $node->attributes;
foreach ($attributes as $attribute) {
//echo ', ' . $attribute->name . '=' . $attribute->value;
}
//echo '<br>';
}
} else {
if ($bLink || $node->nodeName == 'img' || $node->nodeName == '#cdata-section' || $node->nodeName == '#comment' || trim($node->nodeValue) == '') {
continue;
//echo $indent;
//echo 'NO replace: ';
//var_dump($node->nodeValue);
//echo '<br><br>';
} elseif (!$bLink && $node->nodeName != 'img' && trim($node->nodeValue) != '') {
//echo $indent;
//echo "TEXT TO REPLACE: $element, $replace, $node->nodeValue, $iSearchLinks <br>";
$i = 0;
$n = 1;
while (i != $iSearchLinks && $n > 0 ) {
//echo "Create link? <br>";

$node->nodeValue = preg_replace('/'.$element->name.'/', '', $node->nodeValue, 1, $n);
if ($n > 0) {
//echo "Creating link with $element->name <br>";
$link = $dom->createElement("a", $element->name);
$link->setAttribute("class", "nl_tag");
$link->setAttribute("id", "@@ID@@");
$link->setAttribute("hreflang", $element->type);
$link->setAttribute("title", $element->altname);
$link->setAttribute("href", $element->resource);
if ($sRel == "nofollow") $link->setAttribute("rel", $sRel);
if ($sTarget == "_blank") $link->setAttribute("target", $sTarget);
$node->parentNode->appendChild($link);
//var_dump($node->parentNode);
$dom->encoding = 'UTF-8';
$dom->saveHTML();
$iQuantityTopics++;
}
$i++;
//saveHTML?
//echo '<br><br>';
}
}
}

此解决方案不起作用,因为 appendChild 函数仅在子项的末尾添加新的子项,但我想将其添加到找到的要替换的单词所在的位置。

我还尝试将带有 preg_replace 函数的链接直接添加到叶文本节点中,但是 anchor 作为“文本格式”添加到文本节点中,我需要将其添加为链接节点以替换叶中的单词所在的文本节点。

我的问题是:是否可以使用 PHP 中的 html 解析器来执行此操作,或者我必须求助于正则表达式?提前致谢!

最佳答案

@Suamere:

“我不确定 PHP 引擎不支持什么:(?i)(?<!<[^>]*|>)(strWord)(?!<|[^<]*>) "
(?i) - 是的,尽管将 i 放在最后会更容易:

/(someregex)/i<br>
(?&lt;!<[^>]\*|>)

您在这里寻找前导标签;我通过删除第一个 <(某种)

来让它工作

所以这就是最终的正则表达式的样子,它尽可能接近你想要做的事情:

/(?!<[^>]\*>).\*(strWord).\*(?!<\/[^<]\*>)/i<br>

但是,更简单的方法是:

$text = "...";<br>
$words = array('him', 'her', ...);<br>
$links = array('&lt;a href="...">$0&lt;/a>', ...);<br>

foreach ($words as $word) {<br>
&emsp;array_push($regexes, "/\b{$word}\b/i");<br>
}<br>
$modified_array = preg_replace($regexes, $links, $text);<br>

重要的是 $words 和 $links 具有完全相同数量的元素;否则会抛出错误。

$0 引用对应正则表达式的整个匹配;在这种情况下,只有您要查找的特定词本身。

此外,preg_replace() 默认应用/g 修饰符,因此每个正则表达式都不需要该修饰符。 :-)

关于php - PHP 中的 Walking Dom 将找到的字符串列表替换为 "HTML text",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16439878/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com