我想将字符串中的所有文本转换为 html 实体,但保留 HTML 标签,例如:
<p><font style="color:#FF0000">Camión español</font></p>
应该翻译成这样:
<p><font style="color:#FF0000">Camión español</font></p>
有任何想法吗?
我想将字符串中的所有文本转换为 html 实体,但保留 HTML 标签,例如:
<p><font style="color:#FF0000">Camión español</font></p>
应该翻译成这样:
<p><font style="color:#FF0000">Camión español</font></p>
有任何想法吗?
htmlentities
您可以使用函数获取对应字符 => 实体使用的列表get_html_translation_table
;考虑这段代码:
$list = get_html_translation_table(HTML_ENTITIES);
var_dump($list);
(您可能需要在手册中检查该函数的第二个参数——也许您需要将其设置为不同于默认值的值)
它会给你这样的东西:
array
' ' => string ' ' (length=6)
'¡' => string '¡' (length=7)
'¢' => string '¢' (length=6)
'£' => string '£' (length=7)
'¤' => string '¤' (length=8)
....
....
....
'ÿ' => string 'ÿ' (length=6)
'"' => string '"' (length=6)
'<' => string '<' (length=4)
'>' => string '>' (length=4)
'&' => string '&' (length=5)
现在,删除你不想要的对应:
unset($list['"']);
unset($list['<']);
unset($list['>']);
unset($list['&']);
现在,您的列表包含 htmlentites 使用的所有对应字符 => 实体,除了您不想编码的少数字符。
现在,您只需提取键和值列表:
$search = array_keys($list);
$values = array_values($list);
最后,您可以使用 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);
你得到:
string '<p><font style="color:#FF0000">Camión español</font></p>' (length=84)
这看起来像你想要的;-)
编辑:好吧,除了编码问题(该死的 UTF-8,我想——我正在尝试为此找到解决方案,并将再次编辑)
几分钟后的第二次编辑:看来您必须utf8_encode
在$search
列表中使用,然后再调用str_replace
:-(
这意味着使用这样的东西:
$search = array_map('utf8_encode', $search);
在调用 toarray_keys
和调用 to之间str_replace
。
而且,这一次,你应该真的得到你想要的:
string '<p><font style="color:#FF0000">Camión español</font></p>' (length=70)
这是代码的完整部分:
$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);
和完整的输出:
string '<p><font style="color:#FF0000">Camión español</font></p>' (length=58)
string '<p><font style="color:#FF0000">Camión español</font></p>' (length=70)
这次应该没问题了^^
真的不是一行,可能不是最优化的方案;但它应该可以正常工作,并且具有允许您添加/删除任何对应字符 => 您需要或不需要的实体的优点。
玩得开心 !
可能效率不高,但确实有效
$sample = '<p><font style="color:#FF0000">Camión español</font></p>';
echo htmlspecialchars_decode(
htmlentities($sample, ENT_NOQUOTES, 'UTF-8', false)
, ENT_NOQUOTES
);
这是已接受答案的优化版本。
$list = get_html_translation_table(HTML_ENTITIES);
unset($list['"']);
unset($list['<']);
unset($list['>']);
unset($list['&']);
$string = strtr($string, $list);
没有解析器的解决方案对于所有情况都是正确的。你的情况很好:
<p><font style="color:#FF0000">Camión español</font></p>
但你是否也想支持:
<p><font>true if 5 < a && name == "joe"</font></p>
你希望它在哪里出现:
<p><font>true if 5 < a && name == "joe"</font></p>
问题:您可以在构建 HTML 之前进行编码吗?换句话说,可以执行以下操作:
"<p><font>" + htmlentities(inner) + "</font></p>"
如果你能做到这一点,你会为自己省去很多悲伤。如果不能,您将需要某种方法来跳过编码 <、> 和 "(如上所述),或者简单地对其进行编码,然后撤消它(例如。replace('<', '<')
)
无需翻译表或自定义功能的一站式解决方案:
我知道这是一个老问题,但我最近不得不将一个静态网站导入一个 wordpress 网站,并且必须克服这个问题:
这是我不需要摆弄翻译表的解决方案:
htmlspecialchars_decode( htmlentities( html_entity_decode( $string ) ) );
当应用于 OP 的字符串时:
<p><font style="color:#FF0000">Camión español</font></p>
输出:
<p><font style="color:#FF0000">Camión español</font></p>
当应用于 Luca 的字符串时:
<b>Is 1 < 4?</b>è<br><i>"then"</i> <div style="some:style;"><p>gain some <strong>€</strong><img src="/some/path" /></p></div>
输出:
<b>Is 1 < 4?</b>è<br><i>"then"</i> <div style="some:style;"><p>gain some <strong>€</strong><img src="/some/path" /></p></div>
这是我刚刚编写的一个函数,它以一种非常优雅的方式解决了这个问题:
首先,将从字符串中提取 HTML 标签,然后对每个剩余的子字符串执行 htmlentities(),然后将原始 HTML 标签插入到它们的旧位置,从而不会导致 HTML 标签的交替。:-)
玩得开心:
function htmlentitiesOutsideHTMLTags ($htmlText)
{
$matches = Array();
$sep = '###HTMLTAG###';
preg_match_all("@<[^>]*>@", $htmlText, $matches);
$tmp = preg_replace("@(<[^>]*>)@", $sep, $htmlText);
$tmp = explode($sep, $tmp);
for ($i=0; $i<count($tmp); $i++)
$tmp[$i] = htmlentities($tmp[$i]);
$tmp = join($sep, $tmp);
for ($i=0; $i<count($matches[0]); $i++)
$tmp = preg_replace("@$sep@", $matches[0][$i], $tmp, 1);
return $tmp;
}
根据bflesch的回答,我做了一些更改来管理包含less than sign
,greater than sign
和single quote
or的字符串double quotes
。
function htmlentitiesOutsideHTMLTags ($htmlText, $ent)
{
$matches = Array();
$sep = '###HTMLTAG###';
preg_match_all(":</{0,1}[a-z]+[^>]*>:i", $htmlText, $matches);
$tmp = preg_replace(":</{0,1}[a-z]+[^>]*>:i", $sep, $htmlText);
$tmp = explode($sep, $tmp);
for ($i=0; $i<count($tmp); $i++)
$tmp[$i] = htmlentities($tmp[$i], $ent, 'UTF-8', false);
$tmp = join($sep, $tmp);
for ($i=0; $i<count($matches[0]); $i++)
$tmp = preg_replace(":$sep:", $matches[0][$i], $tmp, 1);
return $tmp;
}
使用示例:
$string = '<b>Is 1 < 4?</b>è<br><i>"then"</i> <div style="some:style;"><p>gain some <strong>€</strong><img src="/some/path" /></p></div>';
$string_entities = htmlentitiesOutsideHTMLTags($string, ENT_QUOTES | ENT_HTML401);
var_dump( $string_entities );
输出是:
string '<b>Is 1 < 4?</b>è<br><i>"then"</i> <div style="some:style;"><p>gain some <strong>€</strong><img src="/some/path" /></p></div>' (length=150)
ent flag
您可以根据htmlentities 手册
传递任何内容