我必须使用 Java 来解析我无法控制的系统的输出。它输出包含类似于以下内容的节点的 XML 文件:
<text>
Sample data
On multiple lines</text>
但是,有时数据包含 Unicode 符号,例如 右单引号
’
,其输出如下(由普通文本包围):
<text>’</text>
使用十六进制编辑器,文件中 â 的字节为
C3A2
。
对于我收到的💯表情符号:
<text>💯</text>
ð 的字节为
C3B0
, ´ 的字节为 C2AF
我可以轻松地将转义字符替换为相应的字节,例如
80
和99
,但是是否可以检测其他错误字符、受影响部分的长度并将其替换为正确的Unicode字符?
正确的解决方案是让输出这些垃圾的系统的所有者来纠正它。
如果这确实不可能,您有时可能有机会纠正一些输出。
以第一个例子为例,看看输出是如何被损坏的:
"’"
是“\u2019”
"\u2019".getBytes(StandardCharsets.UTF_8)
给出十六进制的 E2, 80, 99。
生产者将这些字节分别输出为
â
、€
和™
。
您将这些字节保存到文件中,并使用十六进制编辑器查看它们。不要!
最后一步的问题是您自己还创建了一个额外的工件。您已经使用 UTF-8 编码保存了单字节“â”,因此您得到了 CA 32,这是没有用的。不要这样做,因为这会让事情变得更加复杂。 'â' 可以作为单个 Java 字符读取,代码为 '\u00E2'。
所以你现在需要做的就是将这些字节放到一个字节数组中。将“â”保存到单字节0xE2中。取出
"€"
并读取 128 作为十进制值(等于 80 十六进制),并将其存储在下一个字节中。对第三个字节执行相同的操作。然后将字节数组解码回字符串:
new String(bytes, StandardCharsets.UTF_8)
您将得到正确的单引号作为单个 Java 字符。