gpt4 book ai didi

php - 如何在不触及 HTML 元素的情况下修改 HTML 字符串?

转载 作者:行者123 更新时间:2023-12-04 01:13:09 26 4
gpt4 key购买 nike

假设我有这个字符串:

$test = '<p>You are such a <strong class="Stack">helpful</strong> Stack Exchange user.</p>';

然后我天真地用“Flack”替换了“Stack”的任何实例,我会得到这个:

$test = '<p>You are such a <strong class="Flack">helpful</strong> Flack Exchange user.</p>';

显然,我不想要这个。我只想更改实际的“内容”——而不是 HTML 部分。我想要这个:

$test = '<p>You are such a <strong class="Stack">helpful</strong> Flack Exchange user.</p>';

要做到这一点,必须进行某种智能解析。首先检测并从字符串中挑选出 HTML 元素,然后对“纯”内容字符串进行字符串替换操作,然后以某种方式将 HTML 元素原封不动地放回正确的位置。

我的大脑已经为此纠结了很长一段时间,但我找不到任何合理的解决方案,既不会显得骇人听闻又容易出错。

令我震惊的是,这可能作为 PHP 中的一项内置功能而存在。是这样吗?或者有什么方法可以让我以稳健而理智的方式完成这项工作?

我不想尝试用 ____DO_NOT_TOUCH_1________DO_NOT_TOUCH_2____ 等替换所有 HTML 部分。这似乎不是正确的方法。

最佳答案

您可以按照@04FS 的建议进行操作,使用以下递归函数:

function replaceText(DOMNode $node, string $search, string $replace) {
if($node->hasChildNodes()) {
foreach($node->childNodes as $child) {
if ($child->nodeType == XML_TEXT_NODE) {
$child->textContent = str_replace($search, $replace, $child->textContent);
} else {
replaceText($child, $search, $replace);
}
}
}
}

由于 DOMDocument 也是一个 DOMNode,您可以直接将其用作函数参数:

$html =
'<div class="foo">
<span class="foo">foo</span>
<span class="foo">foo</span>
foo
</div>';

$doc = new DOMDocument();
$doc->loadXML($html); // alternatively loadHTML(), will throw an error on invalid HTML tags

replaceText($doc, 'foo', 'bar');

echo $doc->saveXML();
// or
echo $doc->saveXML($doc->firstChild);
// ... to get rid of the leading XML version tag

会输出

<div class="foo">
<span class="foo">bar</span>
<span class="foo">bar</span>
bar
</div>

好处:当你想 str_replace 一个属性值时

function replaceTextInAttribute(DOMNode $node, string $attribute_name, string $search, string $replace) {
if ($node->hasAttributes()) {
foreach ($node->attributes as $attr) {
if($attr->nodeName === $attribute_name) {
$attr->nodeValue = str_replace($search, $replace, $attr->nodeValue);
}
}
}
if($node->hasChildNodes()) {
foreach($node->childNodes as $child) {
replaceTextInAttribute($child, $attribute_name, $search, $replace);
}
}
}

好处 2:使函数更具可扩展性

function modifyText(DOMNode $node, callable $userFunc) {
if($node->hasChildNodes()) {
foreach($node->childNodes as $child) {
if ($child->nodeType == XML_TEXT_NODE) {
$child->textContent = $userFunc($child->textContent);
} else {
modifyText($child, $userFunc);
}
}
}
}

modifyText(
$doc,
function(string $string) {
return strtoupper(str_replace('foo', 'bar', $string));
}
);

echo $doc->saveXML($doc->firstChild);

会输出

<div class="foo">
<span class="foo">BAR</span>
<span class="foo">BAR</span>
BAR
</div>

关于php - 如何在不触及 HTML 元素的情况下修改 HTML 字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64206630/

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