不同的UTF-8签名相同的变音符(元音变音) – 2种二元方式来编写变音符号

我有一个很大的问题,在网上找不到任何帮助:

我把一个网页从OSX移到Linux(这两个系统都在de_DE.UTF-8上运行),并运行一个未知的问题:一些文件没有find,但明显存在于硬盘上(明显地)同名。 所有这些文件都包含德语变音符号。

我拿了一个样本图像,从网页上复制原来的request-uri并直接调用它 – 同样的错误。 重写文件名后,它的工作。 是的,我没有输错!

这让我感到吃惊,我看了看apache-log,发现了这些条目:

192.168.56.10 - - [27/Aug/2012:20:03:21 +0200] "GET /images/Sch%C3%B6ne-Lau-150x150.jpg HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/537.1" 192.168.56.10 - - [27/Aug/2012:20:03:57 +0200] "GET /images/Scho%CC%88ne-Lau-150x150.jpg HTTP/1.1" 404 4205 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/537.1" 

这是我要调查的东西…这是我在UTF8图表http://www.utf8-chartable.de/find的 :

 ö c3 b6 LATIN SMALL LETTER O WITH DIAERESIS ¨ cc 88 COMBINING DIAERESIS 

我想你已经听说过死锁了: http : //en.wikipedia.org/wiki/Dead_key如果没有,请阅读文章。 这很有趣;)

这是否意味着,OSX保存所有的分隔符的信件? 这是否真的意味着,OSX将字符ö保存为o和¨,而不是使用组合结果的真实字符?

如果是的话,你知道一个好的脚本,我可以用它来重命名这些文件吗? 这不会是我从OSX移到Linux的第一页…

Solutions Collecting From Web of "不同的UTF-8签名相同的变音符(元音变音) – 2种二元方式来编写变音符号"

这与死锁并不完全一样,但它是相关的。 如你所知,U + 00F6和U + 006F跟U + 0308有相同的视觉效果。

事实上,Unicode规则在认识到对待它们是一样的,这是基于分解的。 字符数据库中有一个分解表,告诉我们U + 00F6 正则分解为U + 006F,然后是U + 0308。

除了规范分解,还有兼容性分解。 这些丢失一些信息,比如²最终分解为2 。 这显然是一个破坏性的变化,但它对搜索什么时候你想要有点模糊(谷歌知道如何搜索fiſh应该返回关于鱼的结果)是有用的。

如果有一个以上的组合角色在一个非组合角色之后,那么只要我们不重新排列同一类角色的组合角色,我们就可以对它们进行重新排序 。 当我们认为把某首曲子放在某些东西上,然后是一个尖锐的口音,一个尖锐的,然后是一个cedilla,并不重要,但是如果我们把一个尖锐的变音和一个变音都写在一个字母上,这显然很重要他们走的方式。

由此,我们有4种正常化形式。 在进行比较之前,将字符串放入适当的规范化表单中,并且不会被绊倒。

NFD:通过正则分解尽可能地分解一切。 按组合类的顺序重新排序组合类,但是保持同一类相同的顺序。

NFC:首先将所有内容都纳入NFD。 如果不存在同一个班级中较早的班级,那么就不断地查看组合字符。 如果有一个等效的单个字符,则将其替换,然后重新进行扫描,以便进一步撰写。

NFKD:像NFD一样,但是使用兼容性分解(破坏性的变化,但是如上所述用于比较)。

NFD:做NFKD,然后按照NFC重新合并规范

还有一些禁止在NFC中使用的重新组合,以便在一个Unicode版本中有效的NFC文本不会停止NFC,如果Unicode有更多的字符添加到它。

对于NFD和NFC来说,NFC显然更加简洁。 这不是最简洁的可能,但它是一个非常简洁,可以测试和/或创建一个非常有效的流式方式。

Mac OSX使用NFD作为文件名。 因为他们是怪人 (好吧,有比这更好的论点,他们只是没有说服我!)

网络字符模型使用NFC。*因此,您应尽可能在网络上使用NFC。 盲目地将内容转换为NFC可能有安全考虑。 但如果从你开始,它应该从NFC开始。

任何处理文本的编程语言都应该有一个很好的将文本规范化为这些形式的方法。 如果你没有投诉(或如果你是开源的,贡献!)。

有关详情,请参阅http://unicode.org/faq/normalization.html ,或者访问http://unicode.org/reports/tr15/

*为了获得更多的乐趣,如果你在XML或者HTML元素的内容的开始处插入了一个以长固体叠加(U + 0338)开始的东西,那么它会把标签的>变成 ,将格式良好的XML变成乱码。 出于这个原因,网络角色模型坚持每个实体本身都必须是NFC,而不是以组合角色开始。

谢谢,Jon Hanna在这里提供了很多背景信息! 这对于得到完整的答案很重要:一种从一种转换到另一种规范化形式的方法。

由于我的更改是在数据库中链接的文件系统(由于文件上传),我现在必须更新我的数据库转储。 在移动过程中文件已经被重命名了(可能是通过FTP客户端…)

在Linux上转换字符集的命令行工具是:

  • iconv – 转换流的内容(也许是一个文件)
  • convmv – 转换目录中的文件名

字符集utf-8-mac(如http://loopkid.net/articles/2011/03/19/groking-hfs-character-encoding中所述 ),我可以在iconv中使用,似乎只存在于OSX系统上所以我必须将我的sql转储到我的mac,转换它并将其移回。 另一种选择是使用convmv将文件重命名为NFD,但是我认为这样会比未来的帮助更受阻碍。

convmv工具具有一个内建(独立于操作系统)选项来执行NFC或NFD兼容的文件名: http ://www.j3e.de/linux/convmv/man/

PHP本身(我的系统 – WordPress基于的语言)在这里支持兼容层: 在PHP中,如何处理HFS +和别处编码文件名的区别? 在为我解决这个问题后,我会去写一些测试,也可能会写一个错误报告给Wordpress和我工作的其他系统;)

Linux发行版将文件名称视为二进制字符串,这意味着不需要进行编码 – 尽管图形shell(Gnome,KDE等)可能会根据环境变量,语言环境等做出一些假设。

另一方面,OS-X需要或强制(我忘记了)自己版本的Unicode规范化UTF-8扩展所有的变音符合并字符。

在Linux上,当人们在文件名中使用Unicode时,他们更倾向于使用UTF-8和预编码字符来表示变音符号。