【问题标题】:Remove all white space between an image tag删除图像标签之间的所有空白
【发布时间】:2014-05-14 21:42:35
【问题描述】:

我让用户提交了一些文本(包括随机的 html 图片链接),然后我尝试从文本中的图片中创建一个基本的 BBCode [img][/img] 标签。

我目前测试的方式是这样的:

字符串(取自随机论坛):

After a fair few years of doing the usual lowering, fitting wheels etc,when it comes to car modifying, we spent a couple of years doing Minimoto racing all round the country in the Southern British Minimoto Championship winning the 2006 Production Privateer Championship.<br /> <br /> <img src="http://i2.photobucket.com/albums/y18/moo0484/scan0001.jpg" border="0" class="tcattdimglink" onload="NcodeImageResizer.createOn(this);" alt="" /><br /> <br /> <img src="http://i2.photobucket.com/albums/y18/moo0484/01072007065.jpg" border="0" class="tcattdimglink" onload="NcodeImageResizer.createOn(this);" alt="" /><br />

然后我使用函数替换任何图像属性/将图像标签更改为 bbcode:

function convert($text) {
  $text = preg_replace('/class=".*?"/', '', $text);
  $text = preg_replace('/alt=".*?"/', '', $text);
  $text = preg_replace('/src="/', '', $text);
  $text = preg_replace('/border=".*?"/', '', $text);
  $text = preg_replace('/onload=".*?"/', '', $text);
  $text = str_replace("<img", "[img]", "$text");
  $text = str_replace('">', "[/img]", "$text");
  return nl2br($text);
}

如果标签没有以斜杠结尾,这将非常有效。我可以添加另一个规则:

  $text = str_replace('"/>', "[/img]", "$text");

这会起作用,但是我删除属性的地方仍然留下空白。

所以我的问题是,我可以删除 img 标签之间的空白吗:

  <img />

例如,在 preg_replace 函数中的 .*?替换“”之间的内容。

我可以做类似的事情,但使用 img 标签并删除它们之间的空白吗?

我显然不能只跑:

  $text = preg_replace('/\s+/', '', $text);

因为我需要文本中的空白等。

谢谢!

【问题讨论】:

  • 您似乎正在尝试将正则表达式与str_replace 一起使用。你必须使用preg_replace
  • 刚刚改回来,之前使用的是 preg_replace 但决定将其更改为 str... 现在回到 preg 谢谢!
  • sidenote 你应该通过htmlpurifier 运行 html,在进行 bbcode 对话之前,你应该使用像 DOMDocument 这样的适当的 HTML 解析器来只提取你想要的东西,或者你让你的访客接触到各种细菌!
  • 暂时下载htmlpurifier。关于从文本的两个指定部分之间删除空格的任何想法?

标签: php html image preg-replace str-replace


【解决方案1】:

您应该删除所有空白和胭脂属性,几乎所有属性,尤其是 on* 事件属性,如 onClick、onBlur。将 XSS 攻击添加到 HTML 中的方法太多了。制作将它们全部清除的东西将无法维护,因此如果您想让用户输入 HTML,请使用 htmlpurifier。它很容易初始化到您的代码中,并且有很多选项。

一个简单的替代方法是只提取 img 的 src,然后删除属性并将 src 放回去并制作一串图像,然后使用 strip_tags() 删除所有 HTML,然后将图像连接到文本上。但是它缺少图像的定位。

类似:

<?php 
$html = <<<DEMO
After a fair <script>alert('XSS');</script>few ...
winning the 2006 Production Privateer Championship.<br /> 
<div style="background-image: url(javascript:alert('XSS'))"></div>
<br /> 
<img src="http://i2.photobucket.com/albums/y18/moo0484/scan0001.jpg" border="0" class="tcattdimglink" onload="NcodeImageResizer.createOn(this);" alt="" /><br /> 
<br /> 
text here
<img src="http://i2.photobucket.com/albums/y18/moo0484/01072007065.jpg" border="0" class="tcattdimglink" onload="NcodeImageResizer.createOn(this);" alt="" /><br />
more txt here
DEMO;

$dom = new DOMDocument;
@$dom->loadHTML($html);

$xpath = new DOMXPath($dom);

if (false === ($elements = $xpath->query("//*"))) die('Error');

foreach ($elements as $element) {

    //remove script tags
    if($element->nodeName=='script'){
        $element->parentNode->removeChild($element);
    }

    //remove empty tags but not images
    if (!$element->hasChildNodes() || $element->nodeValue == '') {
        if($element->nodeName != 'img'){
            $element->parentNode->removeChild($element);
        }
    }

    //remove all attributes except links and imgs
    for ($i = $element->attributes->length; --$i >= 0;) {
        $name = $element->attributes->item($i)->name;
        if (('img' === $element->nodeName && 'src' === $name) || ('a' === $element->nodeName && 'href' === $name)){
            continue;
        }
        $element->removeAttribute($name);
    }
}

//put dom together and remove the document body
echo preg_replace('~<(?:!DOCTYPE|/?(?:html|body))[^>]*>\s*~i', '', $dom->saveHTML());

/*
<p>After a fair few ...
winning the 2006 Production Privateer Championship.</p>
<img src="http://i2.photobucket.com/albums/y18/moo0484/scan0001.jpg"> 
text here
<img src="http://i2.photobucket.com/albums/y18/moo0484/01072007065.jpg">
more txt here
*/

虽然只是考虑使用htmlpurifier,但 1990 年代的人也呼吁他们希望 BBCODE 回来使用降价。 ;p

祝你好运

【讨论】:

  • 太棒了,谢谢!深入了解它有点累,但它在测试环境中完美运行!明天我会好好阅读,并将其纳入当前流程:)
  • 我更新了答案,第一句话令人困惑,哈哈。祝你好运
  • 如果你想要 BBCODE 转 HTML,heres one
  • 我有使用 BBCode 的理由 :) 我试图将用户转换为使用我的网站并“导入”他们的论坛主题。论坛用户将无法使用 html markdown,但不习惯于简单的 BBCode 标签。所以我要做的是让他们将 BBcode 插入我的网站,并将他们放入的任何 html 转换为 BB 代码,然后将其保存到我的数据库中。显示数据时,我可以轻松地将 BBCode 转换为降价,以便我可以随心所欲地显示。当用户想要编辑帖子时,他们会看到 DB 行,所以它仍然是 BBCode。我正在使用 ckeditor,我很确定它会删除“坏”代码。
  • 有没有办法使用您发布的这种方法但不将图像添加到文本的末尾?如果一个字符串在文本之间混合了图像,我希望图像保持在原来的位置。如果可能的话。
猜你喜欢
  • 1970-01-01
  • 2018-08-14
  • 1970-01-01
  • 2014-05-21
  • 1970-01-01
  • 2012-12-27
  • 1970-01-01
  • 1970-01-01
  • 2015-04-09
相关资源
最近更新 更多