Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/274.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何在不接触HTML元素的情况下修改HTML字符串?_Php_Html_String_Parsing - Fatal编程技术网

Php 如何在不接触HTML元素的情况下修改HTML字符串?

Php 如何在不接触HTML元素的情况下修改HTML字符串?,php,html,string,parsing,Php,Html,String,Parsing,假设我有这个字符串: $test = '<p>You are such a <strong class="Stack">helpful</strong> Stack Exchange user.</p>'; $test='您是一位非常有帮助的childNodes作为$child){ if($child->nodeType==XML\u TEXT\u节点){ $child->textContent=str_replace($se

假设我有这个字符串:

$test = '<p>You are such a <strong class="Stack">helpful</strong> Stack Exchange user.</p>';
$test='您是一位非常有帮助的堆栈交换用户。

然后我天真地用“Flack”替换“Stack”的任何实例,我将得到以下结果:

$test = '<p>You are such a <strong class="Flack">helpful</strong> Flack Exchange user.</p>';
$test='您是一位非常有帮助的Flack Exchange用户。

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

$test = '<p>You are such a <strong class="Stack">helpful</strong> Flack Exchange user.</p>';
$test='您是一位非常有帮助的Flack Exchange用户。

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

我的大脑已经为此绞尽脑汁很长一段时间了,我找不到任何合理的解决方案,而这些解决方案既不老练又容易出错

我突然想到,这可能是PHP内置的一个特性。是这样吗?或者有什么方法可以让我以一种稳健而理智的方式完成这一任务


我不想尝试用
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

函数replaceText(DOMNode$node,string$search,string$replace){
如果($node->hasChildNodes()){
foreach($node->childNodes作为$child){
if($child->nodeType==XML\u TEXT\u节点){
$child->textContent=str_replace($search,$replace,$child->textContent);
}否则{
replaceText($child,$search,$replace);
}
}
}
}
由于
DOMDocument
也是一个
DOMNode
,您可以直接将其用作函数参数:

$html=
'
福
福
福
';
$doc=新的DOMDocument();
$doc->loadXML($html);//或者,loadHTML()将在无效的HTML标记上引发错误
replaceText($doc,'foo,'bar');
echo$doc->saveXML();
//或
echo$doc->saveXML($doc->firstChild);
// ... 要去掉前面的XML版本标记
将输出


酒吧
酒吧
酒吧
奖励:当您想要替换属性值时

函数replaceTextInAttribute(DOMNode$node,string$attribute\u name,string$search,string$replace){
如果($node->hasAttributes()){
foreach($node->attributes as$attr){
如果($attr->nodeName==$attribute\u name){
$attr->nodeValue=str_replace($search,$replace,$attr->nodeValue);
}
}   
}
如果($node->hasChildNodes()){
foreach($node->childNodes作为$child){
replaceTextInAttribute($child、$attribute\u name、$search、$replace);
}
}
}
奖励2:使功能更具可扩展性

函数修改文本(DOMNode$node,可调用$userFunc){
如果($node->hasChildNodes()){
foreach($node->childNodes作为$child){
if($child->nodeType==XML\u TEXT\u节点){
$child->textContent=$userFunc($child->textContent);
}否则{
modifyText($child$userFunc);
}
}
}
}
修改文本(
$doc,
函数(字符串$string){
返回strtoupper(str_replace('foo','bar',$string));
}
);
echo$doc->saveXML($doc->firstChild);
将输出


酒吧
酒吧
酒吧

使用DOM解析器,然后在所有节点上递归迭代,并仅在实际文本节点上进行替换。