在尝试使用GSON处理JSON响应时(输出来自flickr API,以防你问)我遇到了我所描述的某些特殊字符的奇怪编码:
以下是它的十六进制视图:
'u'后跟'双点'是德国人'ü',这就是我的困惑开始的地方。就好像有人拿了这个字母并把它撕成两半,然后对这两个字母进行编码。下图显示了在'ü'被正确编码的情况下我所期望的十六进制编码:
更奇怪的是,在我预计会出现问题的情况下(即亚洲字符集),一切似乎都很好,例如“title”:“ナガレテユク···”
问题:
答案 0 :(得分:5)
您看到的是Unicode decomposition的案例:
德语变音符号等字符可以用两种方式表达:
ü
或u
后跟combining diaeresis ̈_
(我必须在此处使用下划线才能显示它,因为它不应该独立存在,它确实是只是“徘徊点”)如果您收到类似的内容,可以使用java.text.Normalizer
(自Java 1.6以来可用)轻松转换为预先组合的表单:
String decomposed = "Mitgef\u0308hl";
printChars(decomposed); // Mitgefühl -- [M, i, t, g, e, f, u, ̈, h, l]
String precomposed = Normalizer.normalize(decomposed, Form.NFC);
printChars(precomposed); // Mitgefühl -- [M, i, t, g, e, f, ü, h, l]
// Normalizing with NFC again doesn't hurt:
String precomposedAgain = Normalizer.normalize(precomposed, Form.NFC);
printChars(precomposedAgain); // Mitgefühl -- [M, i, t, g, e, f, ü, h, l]
...
static void printChars(String s) {
System.out.println(s + " -- " + Arrays.toString(s.toCharArray()));
}
正如您所看到的,将NFC应用于已经预先组合的字符串并不会造成伤害。
请注意,打印String
将在任何支持Unicode的终端上正确显示,只有在打印字符数组时才能看到分解和预组合表单之间的区别。
可能的来源可能是MacOS,它倾向于以分解形式对事物进行编码,但很奇怪Flickr并没有规范化这些东西。