Преобразование Unicode из строки JSON с помощью PHP

Я читал несколько решений, но пока ничего не смог заставить работать.

У меня есть строка 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?

ОБНОВИТЬ

Кажется, что строка JSON из API имеет 2 или 3 строки Unicode Unicode, например:

 That\u00e2\u0080\u0099s (right single quotation) \u00c2\u00a (pound symbol) 

Это не кодировка UTF-16. Это скорее похоже на фиктивное кодирование, потому что кодировка \ uXXXX не зависит от кодировок UTF или UCS для Unicode. \u00c2\u00a3 действительно отображает строку £ .

То, что вам нужно, это \u00a3 который является кодовой точкой юникода для £ .

{0xC2, 0xA3} – это 2-байтовый символ с кодировкой UTF-8 для этой кодовой точки.

Если, как я думаю, программное обеспечение, закодированное исходной строкой UTF-8 в JSON, не обратило внимания на то, что это был UTF-8 и слепо закодировал каждый байт в escape-код юникода, тогда вам нужно преобразовать каждую пару кода юникода указывает на кодированный символ 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; } 

Edit 2: исправлена ​​предыдущая функция, чтобы преобразовать произвольную последовательность символов unfode unicode utf-8 в эквивалентный символ utf-8.

Будьте осторожны, что некоторые из этих символов, которые, вероятно, поступают из редактора, такого как Word, не могут быть переведены в ISO-8859-1, поэтому будут отображаться как «?» после ut8_decode.

Выход правильный.

 \u00c2 == Â \u00a3 == £ 

Поэтому здесь нет ничего плохого. И преобразование в HTML-объекты легко:

 htmlentities($title);