如何在PHP中解码数字HTML实体

Yur*_*riy 13 php decode html-entities

我正在尝试将编码的长短划线从数字实体解码为字符串,但似乎我找不到能够正确执行此操作的函数.

我找到的最好的是mb_decode_numericentity(),但由于某种原因,它无法解码长划线和其他一些特殊字符.

$str = '–';

$str = mb_decode_numericentity($str, array(0xFF, 0x2FFFF, 0, 0xFFFF), 'ISO-8859-1');
Run Code Online (Sandbox Code Playgroud)

这将返回"?".

谁知道如何解决这个问题?

Pek*_*ica 19

以下代码片段(大部分从此处被盗并经过改进)将适用于文字,数字十进制和数字十六进制实体:

header("content-type: text/html; charset=utf-8");

/**
* Decodes all HTML entities, including numeric and hexadecimal ones.
* 
* @param mixed $string
* @return string decoded HTML
*/

function html_entity_decode_numeric($string, $quote_style = ENT_COMPAT, $charset = "utf-8")
{
$string = html_entity_decode($string, $quote_style, $charset);
$string = preg_replace_callback('~&#x([0-9a-fA-F]+);~i', "chr_utf8_callback", $string);
$string = preg_replace('~&#([0-9]+);~e', 'chr_utf8("\\1")', $string);
return $string; 
}

/** 
 * Callback helper 
 */

function chr_utf8_callback($matches)
 { 
  return chr_utf8(hexdec($matches[1])); 
 }

/**
* Multi-byte chr(): Will turn a numeric argument into a UTF-8 string.
* 
* @param mixed $num
* @return string
*/

function chr_utf8($num)
{
if ($num < 128) return chr($num);
if ($num < 2048) return chr(($num >> 6) + 192) . chr(($num & 63) + 128);
if ($num < 65536) return chr(($num >> 12) + 224) . chr((($num >> 6) & 63) + 128) . chr(($num & 63) + 128);
if ($num < 2097152) return chr(($num >> 18) + 240) . chr((($num >> 12) & 63) + 128) . chr((($num >> 6) & 63) + 128) . chr(($num & 63) + 128);
return '';
}


$string ="&#x201D;"; 

echo html_entity_decode_numeric($string);
Run Code Online (Sandbox Code Playgroud)

欢迎改进建议.

  • 另一个改进:这段代码有一个可怕的内存泄漏.每次调用此函数时,使用create_function()创建的新lambda函数都会卡在内存中.是的,preg_replace_callback()上的手册表明lambda函数是一个"好主意",可以使代码看起来更干净.但这是错误的.创建一个简单的实函数`函数chr_utf8_callback($ matches){return chr_utf8(hexdec($ matches [1])); ``并使用它来代替`$ string = preg_replace_callback('〜&#x([0-9a-fA-F] +);〜我',chr_utf8_callback,$ string);`内存泄漏消失了. (2认同)

Ant*_*ony 1

mb_decode_numericentity不处理十六进制,只处理十进制。您是否得到了预期的结果:

\n\n
$str = '\xe2\x80\x93';\n\n$str = mb_decode_numericentity ( $str , Array(255, 3145727, 0, 65535) , 'ISO-8859-1');\n
Run Code Online (Sandbox Code Playgroud)\n\n

您可以使用hexdec将十六进制转换为十进制。

\n\n

另外,出于好奇,做了以下工作:

\n\n
$str = '&#8211;';\n\n $str = html_entity_decode($str);\n
Run Code Online (Sandbox Code Playgroud)\n