2013-04-10 4 views
0

У меня небольшая проблема с кодировкой utf8. Слово, которое я пытаюсь кодировать, это «kühl». Значит, в нем есть специальный символ.Различные кодировки utf8?

Когда я закодировать эту строку с utf8 в первом файле я получаю:

kühl

Когда я закодировать эту строку с utf8 во втором файле я получаю:

kuÌhl

С php utf8_encode() я всегда получаю первый (kühl) в качестве вывода, но мне нужен второй в качестве вывода (kuÌ hl).

mb_detect_encoding говорит мне, что для обоих это «UTF-8», поэтому это действительно не помогает.

Есть ли у вас идеи получить второй результат? благодарим заранее!

+0

Когда я проверяю kühl в блокноте ++ и выбираю UTF-8, это нормально. Второй кажется странным. – Kaffee

+0

любая идея, что вторая может быть? Я не понимаю, почему mb_detect_encoding говорит мне, что это также UTF-8 – user2266317

+0

Я предполагаю, что ваши файлы сценариев сохраняются с использованием разных кодировок символов - поэтому на самом деле вы не кодируете UTF8 в одной и той же последовательности байтов в этих двух случаях, но разные. – CBroe

ответ

4

Существует только одна кодировка под названием UTF-8, но есть несколько способов представления некоторых глифов в Unicode. U+00FC является совместимым с одним символом совместимости с латиницей 1, который отображается как küll в латинском-1, тогда как с верхней части головы kuÌ hl выглядит как полностью разложенное выражение одного и того же символа, то есть U+0075 (u), за которым следует U+0308 (сочетание диарезиса). Смотрите также http://en.wikipedia.org/wiki/Unicode_equivalence#Normalization

vbvntv$ perl -CSD -le 'print "ku\x{0308}hl"' | iconv -f latin1 -t utf8 
ku�hl 
vbvntv$ perl -CSD -le 'print "ku\x{0308}hl"' | xxd 
0000000: 6b75 cc88 686c 0a     ku..hl. 

0x88 не является допустимым символом в Latin-1 так (в моем браузере) отображается как «недопустимый символ» заполнитель (черный алмаз с белым вопросительным знаком в нем), тогда как другие могут увидеть что-то еще или вообще ничего.

Видимо, вы могли бы использовать class.normalize для преобразования между этими двумя формами в PHP:

$normalized = Normalizer::normalize($input, Normalizer::FORM_D); 

Кстати, просмотр UTF8, как Latin-1 и копировать/вставить изображение, как если бы это был фактический реальный текст капризничает в лучшем случае. Если у вас есть вопросы кодирования символов, фактические байты (например, в шестнадцатеричном формате) являются единственным переносным, понятным способом выразить то, что у вас есть. Как ваш компьютер делает его непредсказуемым во многих сценариях, особенно когда кодирование является проблематичным или неизвестным. Я застрял в презентации, которую вы использовали в своем вопросе, но если у вас есть дополнительные вопросы, постарайтесь сформулировать проблему однозначно.

+1

Я хочу, чтобы upvotes для обратного подхода подавать UTF-8 в 'iconv' и сообщать ему преобразовать Latin-1 в UTF-8, чтобы увидеть представление« Latin-1 »в моем терминале UTF-8. – tripleee

+0

большое спасибо! – user2266317

+0

Пожалуйста, исправьте меня, если я ошибаюсь, но это проблема NFC и NFD? Хотя этот ответ очень описателен, он на самом деле не ответил на вопрос, который задал ОП, и как его получить в НФД. – Phil

0

utf8_encode, несмотря на его имя, не магически кодируется в UTF-8.

Он будет работать только в том случае, если ваш источник ISO-8559-1, также известный как латинский-1.

Если ваш источник уже был UTF-8 или любой другой кодировкой, он выдаст сломанные данные.

Смежные вопросы