У меня проблема с преобразованием некоторых закодированных строк в utf-8.
У меня есть список строк, которые в соответствии с документацией являются строками Unicode, закодированными с использованием числовых HTML-сущностей. Некоторые из них:
$str = 'WÖGER'; // seems to be WÖGER
$str = 'Jürgen'; // seems to be Jürgen
$str = 'POßNITZ'; // seems to be POßNITZ
$str = 'SCHLÄGER'; // seems to be SCHLÄGER
Я хочу расшифровать их и преобразовать в utf-8.
Я пробовал оба mb_convert_encoding () с HTML-ENTITIES
а также html_entity_decode (). Мой лучший результат неожиданно был с:
html_entity_decode($str, ENT_COMPAT | ENT_HTML401, 'ISO-8859-1');
и это расшифровано Jürgen
успешно. Однако мне не повезло расшифровывать другие строки из этого списка. Я посмотрел ISO-8859-1 Таблица кодирования и HTML-коды для умлаутов там отличаются от того, что у меня есть в моем списке.
Мой вопрос: я пропустил какой-то очевидный шаг декодирования или что-то не так с исходными строками?
Обновление (2016-06-27): Оригинальные строки были действительно неправильно закодированы. Эти строки являются результатом чтения значений UTF-8 в контексте Latin-1 и последующего кодирования отдельных 1-байтовых символов в виде шестнадцатеричных сущностей, так что по-немецки ü
стал ü
и был закодирован как 2 отдельных символа. Принятый ответ успешно декодирует их прямо в UTF-8.
Насколько я понимаю, хотя я могу ошибаться, символы юникода должны быть представлены их кодовой точкой, а не кодированием отдельных байтов UTF-8, что у вас есть. Так, Ö
было бы лучше представить с помощью Ö
или в названной форме, Ö
,
ENT_XML1
флаг для html_entity_decode
кажется, делает эту работу, хотя я не совсем уверен, что он делает под капотом. Если вы хотите что-то более явное:
preg_replace_callback('/&#x([A-Fa-f0-9]{2});/', function ($m) {
return chr(hexdec($m[1]));
}, $str);
Других решений пока нет …