从 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);
匹配<
后跟一个或多个“不是>
”,直到我们来到space
和style="..."
部分。 /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('/‘/u', '/’/u', '/“/u', '/”/u', '/—/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);
?>
顺便说一句,正如其他人指出的那样,不建议使用正则表达式。
【讨论】:
<p style="something-evil">
- 繁荣。 <p foo="bar" style="something-evil">
- 繁荣。
这显然是根据原始问题中报告的示例精心制作的。无论如何,您可以使用以下方法改进正则表达式: preg_replace('/(.+?)/i' , "
$4
", $links);并且没有繁荣 :) @LorenzoMarcon 谢谢。我刚刚根据您评论的正则表达式添加了反向匹配。【参考方案9】:您可以在客户端处理它,最简单的是使用 jQuery。比如:
$("#tinyMce p").removeAttr("style");
【讨论】:
这是不安全的,因为用户仍然可以篡改提交给服务器的数据。 原发帖人询问如何使用 PHP 而不是 javascript 来做到这一点。引用:“...但是使用 PHP,我想删除样式属性...”以上是关于从 HTML 标记中删除样式属性的主要内容,如果未能解决你的问题,请参考以下文章