从 HTML 标记中删除样式属性

Posted

技术标签:

【中文标题】从 HTML 标记中删除样式属性【英文标题】:Remove style attribute from HTML tags 【发布时间】:2011-07-27 21:33:28 【问题描述】:

我不太擅长正则表达式,但对于 php,我想从 TinyMCE 返回的字符串中的 html 标记中删除 style 属性。

所以将<p style="...">Text</p> 更改为香草<p>Test</p>

我如何使用preg_replace() 函数来实现这一点?

【问题讨论】:

如果此任务不推荐使用正则表达式,那么是什么? 当 html 字符串从 TinyMCE 返回时,您不只是想删除单个属性或手动查看 DOM 树。使用 HTMLPurifier,可以配置为去掉 style= 属性。 【参考方案1】:

实用的正则表达式(<[^>]+) style=".*?" 将在所有合理的情况下解决这个问题。应该删除不是第一个捕获组的匹配部分,如下所示:

$output = preg_replace('/(<[^>]+) style=".*?"/i', '$1', $input);

匹配&lt; 后跟一个或多个“不是&gt;”,直到我们来到spacestyle="..." 部分。 /i 甚至可以与 STYLE="..." 一起使用。将此匹配替换为$1,即捕获的组。如果标签不包含style="...",它将保持标签不变。

【讨论】:

+1 --- 当用户在智能编辑器中粘贴文本而不在浏览器中使用“粘贴为纯文本”时,仅使用它来消除 Google 协作平台页面中出现的样式垃圾邮件。我使用了 Notepad++ 和替换命令。对于 Notepad++,格式为 \1 而不是 $1 在样式被转义时不起作用。它应该被重构以使其工作,或者 $input 应该被替换为 stripcslashes($input) 您可以运行此命令两次.. 一次用于双引号.. 然后只需将其修改为单引号并再次运行。 太棒了!正是我需要的 我正在使用 Angular js 文本编辑器,我从该文本编辑器中获得了一个值,并将其作为 为您的户外活动和派对或斋月开斋节租用这款白色 PVC 帐篷。可在迪拜租用。  铝结构 PVC 帐篷尺寸 10M x 10M 可在迪拜出租。非常适合聚会和斋月功能。 问题是 它没有样式关键字,那么如何解决这个问题? 【参考方案2】:

我现在正在使用这样的东西来清理标签中的 style='...' 部分,同时保留其他属性。

$output = preg_replace('/<([^>]+)(\sstyle=(?P<stq>["\'])(.*)\k<stq>)([^<]*)>/iUs', '<$1$5>', $input);

【讨论】:

thx 伙计,它为我工作【参考方案3】:
$html = preg_replace('/\sstyle=("|\').*?("|\')/i', '', $html);

用于将所有 style="" 替换为空白。

【讨论】:

【参考方案4】:

除了 Lorenzo Marcon 的回答:

使用preg_replace 选择除样式属性之外的所有内容:

$html = preg_replace('/(<p.+?)style=".+?"(>.+?)/i', "$1$2", $html);

【讨论】:

【参考方案5】:

我评论了@Mayerln 的功能。它确实有效,但 DOMDocument 确实充满了编码。这是我的 simplehtmldom 版本

function stripAttributes($html,$attribs) 
    $dom = new simple_html_dom();
    $dom->load($html);
    foreach($attribs as $attrib)
        foreach($dom->find("*[$attrib]") as $e)
            $e->$attrib = null; 
    $dom->load($dom->save());
    return $dom->save();

【讨论】:

可以确认,这个效果很好! (谢谢你拯救了我的一天) 可以增强此功能以删除任何和所有属性吗?【参考方案6】:

我用这个:

function strip_word_html($text, $allowed_tags = '<a><ul><li><b><i><sup><sub><em><strong><u><br><br/><br /><p><h2><h3><h4><h5><h6>')

    mb_regex_encoding('UTF-8');
    //replace MS special characters first
    $search = array('/&lsquo;/u', '/&rsquo;/u', '/&ldquo;/u', '/&rdquo;/u', '/&mdash;/u');
    $replace = array('\'', '\'', '"', '"', '-');
    $text = preg_replace($search, $replace, $text);
    //make sure _all_ html entities are converted to the plain ascii equivalents - it appears
    //in some MS headers, some html entities are encoded and some aren't
    //$text = html_entity_decode($text, ENT_QUOTES, 'UTF-8');
    //try to strip out any C style comments first, since these, embedded in html comments, seem to
    //prevent strip_tags from removing html comments (MS Word introduced combination)
    if(mb_stripos($text, '/*') !== FALSE)
        $text = mb_eregi_replace('#/\*.*?\*/#s', '', $text, 'm');
    
    //introduce a space into any arithmetic expressions that could be caught by strip_tags so that they won't be
    //'<1' becomes '< 1'(note: somewhat application specific)
    $text = preg_replace(array('/<([0-9]+)/'), array('< $1'), $text);
    $text = strip_tags($text, $allowed_tags);
    //eliminate extraneous whitespace from start and end of line, or anywhere there are two or more spaces, convert it to one
    $text = preg_replace(array('/^\s\s+/', '/\s\s+$/', '/\s\s+/u'), array('', '', ' '), $text);
    //strip out inline css and simplify style tags
    $search = array('#<(strong|b)[^>]*>(.*?)</(strong|b)>#isu', '#<(em|i)[^>]*>(.*?)</(em|i)>#isu', '#<u[^>]*>(.*?)</u>#isu');
    $replace = array('<b>$2</b>', '<i>$2</i>', '<u>$1</u>');
    $text = preg_replace($search, $replace, $text);
    //on some of the ?newer MS Word exports, where you get conditionals of the form 'if gte mso 9', etc., it appears
    //that whatever is in one of the html comments prevents strip_tags from eradicating the html comment that contains
    //some MS Style Definitions - this last bit gets rid of any leftover comments */
    $num_matches = preg_match_all("/\<!--/u", $text, $matches);
    if($num_matches)
        $text = preg_replace('/\<!--(.)*--\>/isu', '', $text);
    
    $text = preg_replace('/(<[^>]+) style=".*?"/i', '$1', $text);
return $text;

【讨论】:

【参考方案7】:

这样的东西应该可以工作(未经测试的代码警告):

<?php

$html = '<p style="asd">qwe</p><br /><p class="qwe">qweqweqwe</p>';

$domd = new DOMDocument();
libxml_use_internal_errors(true);
$domd->loadHTML($html);
libxml_use_internal_errors(false);

$domx = new DOMXPath($domd);
$items = $domx->query("//p[@style]");

foreach($items as $item) 
  $item->removeAttribute("style");


echo $domd->saveHTML();

【讨论】:

对我上面的评论的进一步说明......它确实有效,但 DOMDocument 在 html 实体方面存在问题。它将它们转换为 utf8 字符。所以与贸易;成为 TM。最后我使用了 simplehtmldom 并将我的功能作为答案......【参考方案8】:

给你:

<?php

$html = '<p style="border: 1px solid red;">Test</p>';
echo preg_replace('/<p style="(.+?)">(.+?)<\/p>/i', "<p>$2</p>", $html);

?>

顺便说一句,正如其他人指出的那样,不建议使用正则表达式。

【讨论】:

&lt;p   style="something-evil"&gt; - 繁荣。 &lt;p foo="bar" style="something-evil"&gt; - 繁荣。 这显然是根据原始问题中报告的示例精心制作的。无论如何,您可以使用以下方法改进正则表达式: preg_replace('/

(.+?)/i' , "

$4

", $links);并且没有繁荣 :)
@LorenzoMarcon 谢谢。我刚刚根据您评论的正则表达式添加了反向匹配。【参考方案9】:

您可以在客户端处理它,最简单的是使用 jQuery。比如:

$("#tinyMce p").removeAttr("style");

【讨论】:

这是不安全的,因为用户仍然可以篡改提交给服务器的数据。 原发帖人询问如何使用 PHP 而不是 javascript 来做到这一点。引用:“...但是使用 PHP,我想删除样式属性...”

以上是关于从 HTML 标记中删除样式属性的主要内容,如果未能解决你的问题,请参考以下文章

PHP 如何从网页中删除HTML标记,脚本和样式

如何使用 Jsoup 从 html 元素中删除所有内联样式和其他属性?

PHP 从Drupal节点中删除样式标记

drupal 7删除样式标签形式rss视图字段

怎样用jq在某个样式中删除某一条样式

Gmail 中的 HTML 电子邮件 - 删除了 CSS 样式属性