我一直在阅读一些解决方案,但还没有成功完成任何工作。
我有一个JSON字符串,我从API调用中读取它包含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输出?
更新
似乎来自API的JSON字符串有2或3个未转义的Unicode字符串,例如:
That\u00e2\u0080\u0099s (right single quotation)
\u00c2\u00a (pound symbol)
答案 0 :(得分:10)
不 UTF-16编码。它看起来像是伪造的编码,因为\ uXXXX编码独立于Unicode的任何UTF或UCS编码。 \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之后。
答案 1 :(得分:2)
输出正确。
\u00c2 == Â
\u00a3 == £
这里没有错。转换为HTML实体很容易:
htmlentities($title);
答案 2 :(得分:1)
此处是使用backend : TkAgg
而非with thetop as
(
-- get two first top dates
select *
from
(
select *,
ROW_NUMBER() over (partition by id order by schedule_date desc) rownum
from @t
) x
where x.rownum <= 2
),
thetop2 as
(
-- get data from the next row
select *,
LEAD(schedule_date) over
(partition by id order by rownum) second_max_date,
LEAD(price) over
(partition by id order by rownum) second_max_price
from thetop
)
-- leave first row
select id,
schedule_date as first_max_date,
price as first_max_price,
second_max_date,
second_max_price
from thetop2
where rownum = 1
order by id;
的函数的更新版本。
preg_replace_callback