使用 PHP 从 html 标签中删除属性,同时保留特定属性

Mul*_*tut 2 html php regex

找到了一种使用 php 从 html 字符串中删除所有标签属性的方法:

$html_string = "<div class='myClass'><b>This</b> is an <span style='margin:20px'>example</span><img src='ima.jpg' /></div>";
$output = preg_replace("/<([a-z][a-z0-9]*)[^>]*?(\/?)>/i",'<$1$2>', $html_string);
echo $output;
//<div><b>This</b> is an <span>example</span><img/></div>
Run Code Online (Sandbox Code Playgroud)

但我想保留某些标签,例如 src 和 href。我几乎没有使用常规表达式的经验,因此非常感谢您的帮助。

[也许] 相关更新:这是“清理”数据库帖子的过程的一部分。我正在遍历所有帖子,获取 html,清理它,并在相应的表上更新它。

Dra*_*kes 6

通常不应使用正则表达式解析 HTML。相反,在 PHP 中你应该调用DOMDocument::loadHTML. 然后您可以递归遍历文档中的元素并调用removeAttribute. 众所周知,HTML 标签的正则表达式非常棘手。

参考:http : //php.net/manual/en/domdocument.loadhtml.php

示例:http : //coursesweb.net/php-mysql/html-attributes-php

这是为您提供的解决方案。它将遍历 DOM 中的所有标签,并删除不是src或 的属性href

$html_string = "<div class=\"myClass\"><b>This</b> is an <span style=\"margin:20px\">example</span><img src=\"ima.jpg\" /></div>";

$dom = new DOMDocument;                 // init new DOMDocument
$dom->loadHTML($html_string);           // load the HTML
$xpath = new DOMXPath($dom);
$nodes = $xpath->query('//@*');
foreach ($nodes as $node) {             
    if($node->nodeName != "src" && $node->nodeName != "href") {
        $node->parentNode->removeAttribute($node->nodeName);
    }
}

echo $dom->saveHTML();                  // output cleaned HTML
Run Code Online (Sandbox Code Playgroud)

这是另一种使用 xPath 来过滤属性名称的解决方案:

$dom = new DOMDocument;                 // init new DOMDocument
$dom->loadHTML($html_string);           // load the HTML
$xpath = new DOMXPath($dom);
$nodes = $xpath->query("//@*[local-name() != 'src' and local-name() != 'href']");
foreach ($nodes as $node) {             
    $node->parentNode->removeAttribute($node->nodeName);
}

echo $dom->saveHTML();                  // output cleaned HTML
Run Code Online (Sandbox Code Playgroud)

提示:如果您使用这样的扩展字符,请将 DOM 解析器设置为 UTF-8:

$dom->loadHTML(mb_convert_encoding($html_string, 'HTML-ENTITIES', 'UTF-8'));
Run Code Online (Sandbox Code Playgroud)

  • @CasimiretHippolyte 挑战,接受!Multitut,谢谢你,我会为未来的读者更新我的答案 (2认同)