使用PHP将<tag> </tag>之间的所有内容转换为HTML实体

时间:2011-08-14 22:20:27

标签: php html-entities

如何将标签之间的所有内容转换为html实体:

Lorem ipsum dolor sit amet, consetetur sadipscing elitr,
sed diam nonumy eirmod tempor invidunt ut labore et dolore
magna aliquyam erat, sed diam voluptua.
<code class="highlight sql">
    CREATE TABLE `comments`
</code>

<h1>Next step</h1>

Lorem ipsum dolor sit amet, consetetur sadipscing elitr,
sed diam nonumy eirmod tempor invidunt ut labore et
dolore magna aliquyam erat, sed diam voluptua.
At vero eos et accusam et justo duo dolores et ea rebum.
<b>Stet clita kasd gubergren, no sea takimata sanctus</b> est Lorem
dolor sit amet. Lorem ipsum dolor sit amet, consetetur
sadipscing elitr, sed diam nonumy eirmod tempor invidunt
ut labore et dolore magna aliquyam erat, sed diam voluptua:
<code class="highlight php">
    <?php
        $host = "localhost";
    ?>
</code>

Lorem ipsum dolor sit amet, consetetur sadipscing elitr.

注意:上面的例子是一个我可以在PHP中转换的字符串。

3 个答案:

答案 0 :(得分:2)

这归结为我的正则表达式。在你开始喊叫之前,可以可靠地匹配&amp;只要没有嵌套标记,就替换html的子集。

这是简单的方法。一个正则表达式匹配标签从头到尾,并将一个函数应用于匹配/编码我们需要的东西并替换它。

下面是代码:

<?php
$string = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr,
sed diam nonumy eirmod tempor invidunt ut labore et dolore
magna aliquyam erat, sed diam voluptua.
<code class="highlight sql">
    CREATE TABLE `comments`&
</code>

<h1>Next step</h1>

Lorem ipsum dolor sit amet, consetetur sadipscing elitr,
sed diam nonumy eirmod tempor invidunt ut labore et
dolore magna aliquyam erat, sed diam voluptua.
At vero eos et accusam et justo duo dolores et ea rebum.
<b>Stet clita kasd gubergren&, no sea takimata sanctus</b> est Lorem
dolor sit amet. Lorem ipsum dolor sit amet, consetetur
sadipscing elitr, sed diam nonumy " eirmod " tempor invidunt
ut labore et dolore magna aliq&uyam erat, sed diam voluptua:
<code class="highlight php">
    <?php
       * $host = "localhost";
    ?>&
</code>

Lorem ipsum dolor sit amet, consetetur sadipscing elitr.';

echo preg_replace("/(<code[^>]*?>)(.*?)(<\/code>)/se", "
    stripslashes('$1').
    htmlentities(stripslashes('$2')).
    stripslashes('$3')
", $string);

并且是一个在codepad上运行的测试用例

http://codepad.org/MhKwfOQl

只要没有令人讨厌的嵌套标签/损坏的html,这将有效。

我仍然建议您尝试确保保存数据,因为您希望将数据设为可见,并根据需要进行编码。

如果要在不同的标签集之间进行替换,请更改正则表达式。

更新:似乎$ host正在被php解析...而我们不希望这样。发生这种情况是因为php将替换字符串计算为php,然后执行给定的函数并将找到的字符串输入到这些函数中,如果该字符串由double qoutes封装,它也会解析这些字符串......嘿,这简直是麻烦。

然后又出现了另一个问题,php在匹配中逃脱单个和双重qoutes,因此它们不会生成解析错误,这样一来,比赛中的任何qoutes也必须从他们的斜线中剥离...导致相当长的替换字符串。

答案 1 :(得分:1)

虽然正则表达式或解析器可能会为您解决这个难题,但我认为您可能会以错误的方式实现目标。

  

取自以下评论中的问题:

     

@Poru该字符串是如何生成的?

     

@Phil:从数据库中获取。它的   教程的内容。这是一个自己的开发“CMS”。

如果要将此字符串存储在数据库中,并且其功能是返回HTML内容,则应该将内容存储为HTML,这意味着必须使用等效的HTML实体转义相应的字符。

这是在这个问题中已经提供给你的建议:https://stackoverflow.com/questions/7059776/include-source-code-in-html-valid/7059834

这里解释了必须转义的字符(以及其他各种参考文献):

  

http://php.net/manual/en/function.htmlspecialchars.php

     

执行的翻译是:

     
      
  • '&安培;' (&符号)变为'&amp;'
  •   
  • '“'(双引号)在未设置ENT_NOQUOTES时变为'&quot;'
  •   
  • “'”(单引号)仅在设置ENT_QUOTES时变为'&#039;'
  •   
  • '&LT;' (小于)变为'&lt;'
  •   
  • '&GT;' (大于)变为'&gt;'
  •   

如果实际上是这种情况,并且该字符串应该是HTML输出而没有其他功能,将它保存为无效HTML没有任何意义,或者至少不是你想要的那样

如果您必须存储未转义的代码示例,请考虑为这些代码段设置单独的数据库表,并在将其输出到HTML文档之前简单地对它们运行htmlspecialchars()。您甚至可以为每条记录分配一种语言,并自动为每种情况使用适当的语法高亮工具。

在我看来,在这种情况下,你所尝试的并不是解决这一特定问题的适当方法。转义字符并准备好将HTML内容输出到屏幕中的当前形式是可行的方法。

答案 2 :(得分:0)

$dom = new DOMDocument;
$dom->loadHTML(...);

$tags = $dom->getElementsByTagName('tag');
foreach($tags as $tag) {
    $tag->nodeValue = htmlentities($tag->nodeValue);
}
$dom->saveHTML();