<p><font style="color:#FF0000">Camión español</font></p>
should be translated into this:
<p><font style="color:#FF0000">Camión español</font></p>
有什么想法吗?
<p><font style="color:#FF0000">Camión español</font></p>
should be translated into this:
<p><font style="color:#FF0000">Camión español</font></p>
有什么想法吗?
你可以使用get_html_translation_table
函数来获取被htmlentities
使用的字符与实体对应关系列表;考虑下面的代码:
$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,我猜测--我正在尝试找到解决方法,并会再次编辑)
几分钟后第二次编辑:看起来你需要在调用str_replace
之前,在$search
列表上使用utf8_encode
:-(
也就是说,要使用类似于以下的内容:
$search = array_map('utf8_encode', $search);
在调用 array_keys
和调用 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)
这次应该没问题了 ^^
它可能不能适用于单行,也许不是最优化的解决方案; 但它应该可以正常工作,并且具有允许您添加/删除所需或不需要的任何对应字符=>实体的优点。
玩得开心!
strtr
,但这破坏了编码。 - Horen可能不是非常高效,但它能正常工作
$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);
$list = get_html_translation_table(HTML_ENTITIES); unset($list['"'], $list['<'], $list['>'], $list['&']); echo strtr($val, $list);
- Dmitri Zaitsev除了解析器,没有其他方法能够适用于所有情况。您的情况很好:
<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>
htmlspecialchars_decode( htmlentities( $string ) );
- 如果您不删除第三个函数调用,输入字符串 <p>The HTML you want is "1 > 0"</p>
将变成 <p>The HTML you want is "1 > 0"</p>
,这是不正确的,可能会存在安全漏洞。 - M Somervillehtml_entity_decode()
--您能解释一下将HTML转换的安全风险吗?例如,没有提到公共表单提交...边缘情况不在本帖子的范围内--也许您可以开始一个解决您所指出问题的帖子。 - aequalsbfunction 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的答案,我对代码进行了一些更改以处理包含小于号
、大于号
、单引号
或双引号
的字符串。
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)
您可以根据htmlentities手册传递任何ent标志
。