2013-04-10 126 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 2013-04-10 13:52:01

+0

有什么想法第二个可能是什么?我不明白为什么mb_detect_encoding告诉我它也是UTF-8 – user2266317 2013-04-10 13:57:32

+0

我假设你的脚本文件是使用不同的字符编码保存的 - 所以你的实际上并不是UTF8编码,而是在这两种情况下编码相同的字节序列,但是不同的编码。 – CBroe 2013-04-10 14:16:19

回答

4

只有一种编码称为UTF-8,但有多种方式可以用Unicode表示一些字形。 U+00FC是拉丁语-1兼容性的单字形预分解ü,其在拉丁语-1中显示为kühl,而关闭我的头顶部kuÌ hl看起来像是相同字符的完全分解的表达,即U+0075(u),随后是U+0308(结合diaeresis)。另请参见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拉丁-1和复制/粘贴表示,就好像它是实际的现实文本是反复无常最好。如果您有字符编码问题,则实际字节(例如,十六进制)是唯一可以用来表达您所拥有的便于理解的方式。在许多情况下,计算机如何呈现它是不可预知的,特别是当编码有问题或未知时。我一直坚持你在你的问题中使用的演示文稿,但如果你有其他问题,请注意清楚地说明问题。

+1

我希望赞成将UTF-8添加到'iconv'并告诉它将Latin-1转换为UTF-8以便在我的UTF-8终端中查看“Latin-1”表示形式的back-asswards方法。 – tripleee 2013-04-10 15:34:35

+0

非常感谢! – user2266317 2013-04-10 18:21:56

+0

如果我错了,请纠正我,但这是NFC vs NFD问题吗?虽然这个回答非常具有描述性,但它并没有真正回答OP询问的问题,即如何在NFD中获得它。 – Phil 2015-05-11 11:11:19

0

utf8_encode,尽管它的名称,不奇迹般地编码为UTF-8。

只有你的源代码是ISO-8559-1,也就是latin-1,它才能工作。

如果您的源已经是UTF-8或任何其他编码,它将输出损坏的数据。