在Java中将十六进制字节数组的字符串表示形式转换为包含非ascii字符的字符串

在Java中将十六进制字节数组的字符串表示形式转换为包含非ascii字符的字符串,java,hex,non-ascii-characters,string-decoding,Java,Hex,Non Ascii Characters,String Decoding,客户端在请求有效负载中发送了一个字符串,如下所示: "[0xc3][0xa1][0xc3][0xa9][0xc3][0xad][0xc3][0xb3][0xc3][0xba][0xc3][0x81][0xc3][0x89][0xc3][0x8d][0xc3][0x93][0xc3][0x9a]Departms" 我想得到一个字符串,它是“áçíóúÁÍÓÚDepartms”。我如何在Java中做到这一点 问题是我无法控制客户端对该字符串的编码方式。客户端似乎只是将非ascii字符编码为这种格式

客户端在请求有效负载中发送了一个字符串,如下所示:

"[0xc3][0xa1][0xc3][0xa9][0xc3][0xad][0xc3][0xb3][0xc3][0xba][0xc3][0x81][0xc3][0x89][0xc3][0x8d][0xc3][0x93][0xc3][0x9a]Departms"
我想得到一个字符串,它是“áçíóúÁÍÓÚDepartms”。我如何在Java中做到这一点


问题是我无法控制客户端对该字符串的编码方式。客户端似乎只是将非ascii字符编码为这种格式,并按原样发送ascii字符(请参见末尾的“Departms”)。

方括号内的内容似乎是UTF-8编码的字符,但以奇怪的方式转换为十六进制字符串。您可以找到每个看起来像
[0xc3]
的实例,并将其转换为相应的字节,然后从字节中创建一个新字符串

String bracketDecode(String str) {
    Pattern p = Pattern.compile("\\[(0x[0-9a-f]{2})\\]");
    Matcher m = p.matcher(str);
    StringBuilder sb = new StringBuilder();
    while (m.find()) {
        String group = m.group(1);
        Integer decode = Integer.decode(group);
        // assume latin-1 encoding
        m.appendReplacement(sb, Character.toString(decode));
    }
    m.appendTail(sb);
    // oh no, latin1 is not correct! re-interpret bytes in utf-8
    byte[] bytes = sb.toString().getBytes(StandardCharsets.ISO_8859_1);
    return new String(bytes, StandardCharsets.UTF_8);
}
不幸的是,没有好的工具来处理字节数组。这里有一个快速而肮脏的解决方案,它使用正则表达式查找这些十六进制代码,并将其替换为相应的拉丁字符-1,然后通过重新解释字节来修复这些问题

String bracketDecode(String str) {
    Pattern p = Pattern.compile("\\[(0x[0-9a-f]{2})\\]");
    Matcher m = p.matcher(str);
    StringBuilder sb = new StringBuilder();
    while (m.find()) {
        String group = m.group(1);
        Integer decode = Integer.decode(group);
        // assume latin-1 encoding
        m.appendReplacement(sb, Character.toString(decode));
    }
    m.appendTail(sb);
    // oh no, latin1 is not correct! re-interpret bytes in utf-8
    byte[] bytes = sb.toString().getBytes(StandardCharsets.ISO_8859_1);
    return new String(bytes, StandardCharsets.UTF_8);
}