我一直在阅读了上几个解决方案,但仍未能得到任何尚未上班。
我有我从API调用读取一个JSON字符串,并将其包含Unicode字符- \u00c2\u00a3
例如是£符号。
我想使用PHP来将这些转换成要么£
或£
。
我寻找到的问题,并发现了下面的代码(使用我的英镑符号测试),但它似乎没有工作:
$title = preg_replace("/\\\\u([a-f0-9]{4})/e", "iconv('UCS-4LE','UTF-8',pack('V', hexdec('U$1')))", '\u00c2\u00a3');
输出是£
。
我在想,这是UTF-16编码是否正确? 我将如何转换这些输出为HTML?
UPDATE
这似乎从API JSON字符串有2个或3转义Unicode字符串,例如:
That\u00e2\u0080\u0099s (right single quotation)
\u00c2\u00a (pound symbol)
它不是 UTF-16编码。 它,而似乎是虚假的编码,因为为\ uXXXX编码是什么UTF或UCS编码对Unicode的独立的。 \u00c2\u00a3
真正映射到£
字符串。
你应该拥有的是\u00a3
这对Unicode代码点£
。
{为0xC2,0xA3执行}是UTF-8编码的2个字节的字符此码点。
如果,因为我认为,原始编码UTF-8字符串JSON,该软件是无视这样的事实,这是UTF-8和盲目编码的每个字节的转义Unicode代码点,那么你需要每对Unicode编码转换指向一个UTF-8编码的字符,然后将其解码成原生PHP编码,使其可打印。
function fixBadUnicode($str) {
return utf8_decode(preg_replace("/\\\\u00([0-9a-f]{2})\\\\u00([0-9a-f]{2})/e", 'chr(hexdec("$1")).chr(hexdec("$2"))', $str));
}
这里的例子: http://phpfiddle.org/main/code/6sq-rkn
编辑:
如果你要修复的字符串,以获得有效的JSON字符串,则需要使用以下功能:
function fixBadUnicodeForJson($str) {
$str = preg_replace("/\\\\u00([0-9a-f]{2})\\\\u00([0-9a-f]{2})\\\\u00([0-9a-f]{2})\\\\u00([0-9a-f]{2})/e", 'chr(hexdec("$1")).chr(hexdec("$2")).chr(hexdec("$3")).chr(hexdec("$4"))', $str);
$str = preg_replace("/\\\\u00([0-9a-f]{2})\\\\u00([0-9a-f]{2})\\\\u00([0-9a-f]{2})/e", 'chr(hexdec("$1")).chr(hexdec("$2")).chr(hexdec("$3"))', $str);
$str = preg_replace("/\\\\u00([0-9a-f]{2})\\\\u00([0-9a-f]{2})/e", 'chr(hexdec("$1")).chr(hexdec("$2"))', $str);
$str = preg_replace("/\\\\u00([0-9a-f]{2})/e", 'chr(hexdec("$1"))', $str);
return $str;
}
编辑2:固定先前的功能转化任何错误的unicode转义的UTF-8字节序列成等价的UTF-8字符。
请注意,其中有些字符,这可能来自一个编辑器,如Word的是不可翻译为ISO-8859-1,因此将显示为“?” ut8_decode后。
输出是正确的。
\u00c2 == Â
\u00a3 == £
所以,没有什么是错在这里。 并转换成HTML实体很简单:
htmlentities($title);
下面是使用功能的更新版本preg_replace_callback
代替preg_replace
。
function fixBadUnicodeForJson($str) {
$str = preg_replace_callback(
'/\\\\u00([0-9a-f]{2})\\\\u00([0-9a-f]{2})\\\\u00([0-9a-f]{2})\\\\u00([0-9a-f]{2})/',
function($matches) { return chr(hexdec("$1")).chr(hexdec("$2")).chr(hexdec("$3")).chr(hexdec("$4")); },
$str
);
$str = preg_replace_callback(
'/\\\\u00([0-9a-f]{2})\\\\u00([0-9a-f]{2})\\\\u00([0-9a-f]{2})/',
function($matches) { return chr(hexdec("$1")).chr(hexdec("$2")).chr(hexdec("$3")); },
$str
);
$str = preg_replace_callback(
'/\\\\u00([0-9a-f]{2})\\\\u00([0-9a-f]{2})/',
function($matches) { return chr(hexdec("$1")).chr(hexdec("$2")); },
$str
);
$str = preg_replace_callback(
'/\\\\u00([0-9a-f]{2})/',
function($matches) { return chr(hexdec("$1")); },
$str
);
return $str;
}