Java库使用启发式修复编码错误的文本

Java库使用启发式修复编码错误的文本,java,utf-8,character-encoding,heuristics,Java,Utf 8,Character Encoding,Heuristics,我正在处理一个外部web服务,它给了我错误编码(和/或损坏)的字符串(UTF-8),这些字符串很可能是ISO拉丁语或WINDOWS-1252,但现在是UTF-8(和/或ISO/WINDOWS/UTF-8的混合)。可爱的帽子()比比皆是 显然,我无法修复外部web服务如何存储其字符串,从而导致信息丢失。因此,我所知道的100%翻译的希望是不可能的 但我希望有人用Java编写了一个启发式字符映射库(不太可能有人会键入hats) 如果没有,我想我可以移植这段PHP代码: 更新和解释:像@VGR这样的简

我正在处理一个外部web服务,它给了我错误编码(和/或损坏)的字符串(
UTF-8
),这些字符串很可能是
ISO拉丁语
WINDOWS-1252
,但现在是
UTF-8
(和/或ISO/WINDOWS/UTF-8的混合)。可爱的帽子(
)比比皆是

显然,我无法修复外部web服务如何存储其字符串,从而导致信息丢失。因此,我所知道的100%翻译的希望是不可能的

但我希望有人用Java编写了一个启发式字符映射库(不太可能有人会键入hats)

如果没有,我想我可以移植这段PHP代码:

更新和解释:像@VGR这样的简单转换将不起作用。我没有原始字节。数据在端点处的转换不正确(SOAP服务器可能
getBytes(/*没有正确的编码*/)
已完成,或者数据存储格式不正确)。在Java中将字节转换为字符串时,数据不会被保留,除非编码在任何地方都是相同的。如果您想到类似于
ASCII
UTF-8
,这很容易理解。使用
Windows-1252
ISO拉丁语
则要复杂得多,因为数据不会丢失,但经常会混淆。这是因为这些编码可以是两个字节,并且不是
UTF-8
的子集


如果您不相信我,您可以尝试使用各种编码前后执行
getBytes()
,将看到数据损坏和数据丢失。

我可能误解了错误编码数据的性质,但对我来说,PHP代码似乎有些过火。如果您有作为单个字符传递的UTF-8字节,您应该能够执行以下操作:

String fix(String s) {
    byte[] bytes = s.getBytes(Charset.forName("windows-1252"));
    return new String(bytes, StandardCharsets.UTF_8);
}

这不起作用,因为数据已经损坏。如果我有原始字节,那就行了。相信我,你所列出的是我非常清楚的。@AdamAgent这就是PHP代码的作用。。。尽管它应该使用Windows-1252而不是ISO-8859-1。你能举例说明你所拥有的和它应该是什么吗?你是对的;代码已更新。我认为所有UTF-8字节都是有效的ISO-8859-1字符,但事实并非如此。@Esailija上面的代码根本不是PHP代码所做的。PHP代码正在替换基于一些启发式映射的字符字节。它这样做的原因是因为代码假设2字节拉丁/窗口代码与潜在的4字节UTF-8混合,这是我的问题。上面的Java代码将字节放在Unicode(不是UTF-8)中,然后从Unicode转换为基于巨大映射表的字符编码。我不清楚为什么这还不够。如果您知道原始错误编码字节的编码方式,那么使用已知字符集对其进行解码是完全安全可靠的。与不带参数调用String.getBytes不同,带参数调用String.getBytes更可靠,并保证产生可预测的结果。不会丢失任何信息。问题是您的服务无法知道原始编码应该是什么?我不应该让它打扰我,但当有人投票结束而不写评论时,它总是让我烦恼。