PHP中的htmlentities但保留了html标签

fid*_*boy 55 html php string replace html-entities

我想将字符串中的所有文本转换为html实体,但保留HTML标记,例如:

<p><font style="color:#FF0000">Camión español</font></p>
Run Code Online (Sandbox Code Playgroud)

应该翻译成这个:

<p><font style="color:#FF0000">Cami&oacute;n espa&ntilde;ol</font></p>
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

Pas*_*TIN 65

您可以使用htmlentities函数获取对应的列表character => entity使用的实体get_html_translation_table; 考虑这段代码:

$list = get_html_translation_table(HTML_ENTITIES);
var_dump($list);
Run Code Online (Sandbox Code Playgroud)

(您可能需要在手册中检查该功能的第二个参数 - 也许您需要将其设置为与默认值不同的值)

它会得到这样的东西:

array
  ' ' => string '&nbsp;' (length=6)
  '¡' => string '&iexcl;' (length=7)
  '¢' => string '&cent;' (length=6)
  '£' => string '&pound;' (length=7)
  '¤' => string '&curren;' (length=8)
  ....
  ....
  ....
  'ÿ' => string '&yuml;' (length=6)
  '"' => string '&quot;' (length=6)
  '<' => string '&lt;' (length=4)
  '>' => string '&gt;' (length=4)
  '&' => string '&amp;' (length=5)
Run Code Online (Sandbox Code Playgroud)

现在,删除您不想要的对应关系:

unset($list['"']);
unset($list['<']);
unset($list['>']);
unset($list['&']);
Run Code Online (Sandbox Code Playgroud)

您的列表现在具有htmlentites使用的所有对应字符=>实体,除了您不想编码的少数字符.

现在,您只需要提取键和值列表:

$search = array_keys($list);
$values = array_values($list);
Run Code Online (Sandbox Code Playgroud)

最后,您可以使用str_replace进行替换:

$str_in = '<p><font style="color:#FF0000">Camión español</font></p>';
$str_out = str_replace($search, $values, $str_in);
var_dump($str_out);
Run Code Online (Sandbox Code Playgroud)

你得到:

string '<p><font style="color:#FF0000">Cami&Atilde;&sup3;n espa&Atilde;&plusmn;ol</font></p>' (length=84)
Run Code Online (Sandbox Code Playgroud)

看起来像你想要的;-)


编辑:好吧,除了编码问题(该死的UTF-8,我想 - 我正试图找到一个解决方案,并将再次编辑)

第二次编辑几分钟后:看起来你必须utf8_encode$search列表上使用,然后调用str_replace:-(

这意味着使用这样的东西:

$search = array_map('utf8_encode', $search);
Run Code Online (Sandbox Code Playgroud)

呼叫array_keys和呼叫之间str_replace.

而且,这一次,你应该得到你想要的东西:

string '<p><font style="color:#FF0000">Cami&oacute;n espa&ntilde;ol</font></p>' (length=70)
Run Code Online (Sandbox Code Playgroud)


以下是代码的完整部分:

$list = get_html_translation_table(HTML_ENTITIES);
unset($list['"']);
unset($list['<']);
unset($list['>']);
unset($list['&']);

$search = array_keys($list);
$values = array_values($list);
$search = array_map('utf8_encode', $search);

$str_in = '<p><font style="color:#FF0000">Camión español</font></p>';
$str_out = str_replace($search, $values, $str_in);
var_dump($str_in, $str_out);
Run Code Online (Sandbox Code Playgroud)

而全部输出:

string '<p><font style="color:#FF0000">Camión español</font></p>' (length=58)
string '<p><font style="color:#FF0000">Cami&oacute;n espa&ntilde;ol</font></p>' (length=70)
Run Code Online (Sandbox Code Playgroud)

这一次,应该
没问题^^ 它确实不适合一行,可能不是最优化的解决方案; 但它应该工作正常,并且有一个优点,允许您添加/删除任何对应的字符=>您需要或不需要的实体.

玩得开心 !

  • 哇,答案很好,干得好.如果可以,我会给你+3;) (4认同)

Pet*_*ley 18

可能不是非常有效,但它的工作原理

$sample = '<p><font style="color:#FF0000">Camión español</font></p>';

echo htmlspecialchars_decode(
    htmlentities($sample, ENT_NOQUOTES, 'UTF-8', false)
  , ENT_NOQUOTES
);
Run Code Online (Sandbox Code Playgroud)


Sil*_*eNT 7

这是已接受答案的优化版本.

$list = get_html_translation_table(HTML_ENTITIES);
unset($list['"']);
unset($list['<']);
unset($list['>']);
unset($list['&']);

$string = strtr($string, $list);
Run Code Online (Sandbox Code Playgroud)


ndp*_*ndp 5

对于所有情况,解析器之外没有解决方案是正确的.你的是一个很好的案例:

<p><font style="color:#FF0000">Camión español</font></p>
Run Code Online (Sandbox Code Playgroud)

但你也想支持:

<p><font>true if 5 < a && name == "joe"</font></p>
Run Code Online (Sandbox Code Playgroud)

在哪里你想要它出来:

<p><font>true if 5 &lt; a &amp;&amp; name == &quot;joe&quot;</font></p>
Run Code Online (Sandbox Code Playgroud)

问题:您可以在构建HTML之前进行编码吗?换句话说可以做类似的事情:

"<p><font>" + htmlentities(inner) + "</font></p>"
Run Code Online (Sandbox Code Playgroud)

如果你能做到这一点,你将为自己节省很多悲伤.如果你不能,你需要一些方法来跳过编码<,>和"(如上所述),或者只是编码所有,然后撤消它(例如.replace('&lt;', '<'))


aeq*_*lsb 5

无需转换表或自定义函数的单行解决方案:

\n\n

我知道这是一个老问题,但我最近不得不将静态站点导入到 WordPress 站点中,并且必须克服这个问题:

\n\n

这是我的解决方案,不需要摆弄翻译表:

\n\n

htmlspecialchars_decode( htmlentities( html_entity_decode( $string ) ) );

\n\n

当应用于 OP 的字符串时:

\n\n
<p><font style="color:#FF0000">Cami\xc3\xb3n espa\xc3\xb1ol</font></p>\n
Run Code Online (Sandbox Code Playgroud)\n\n

输出:

\n\n
<p><font style="color:#FF0000">Cami&oacute;n espa&ntilde;ol</font></p>\n
Run Code Online (Sandbox Code Playgroud)\n\n

当应用于 Luca 的字符串时:

\n\n
<b>Is 1 < 4?</b>\xc3\xa8<br><i>"then"</i> <div style="some:style;"><p>gain some <strong>\xe2\x82\xac</strong><img src="/some/path" /></p></div>\n
Run Code Online (Sandbox Code Playgroud)\n\n

输出:

\n\n
<b>Is 1 < 4?</b>&egrave;<br><i>"then"</i> <div style="some:style;"><p>gain some <strong>&euro;</strong><img src="/some/path" /></p></div>\n
Run Code Online (Sandbox Code Playgroud)\n

  • 我发现这条简单的线确实工作得很好。向下滚动到最近的答案而不是选择的答案通常是好的。 (2认同)