将包含ISO 8859-1十六进​​制字符代码的字符串转换为UTF-8 Java

时间:2019-07-13 19:16:36

标签: java utf-8 iso-8859-1

我有一个字符串,我相信它包含一些ISO-8859-1十六进​​制字符代码

expect(res).toBeOfType(GetPlayer)

我想将其更改为此,

String doc = "#xC1;o thun b#xE9; g#xE1;i c#x1ED9;t d#xE2;y xanh bi#x1EC3;n"

我尝试过这种方法,但是没有运气

Áo thun bé gái cột dây xanh biển

转换它的正确方法是什么?非常感谢您的帮助!

3 个答案:

答案 0 :(得分:1)

假设#nnnn;序列是普通的旧Unicode字符表示,我建议采用以下方法。

class Cvt {

    static String convert(String in) {
        String str = in;
        int curPos = 0;
        while (curPos < str.length()) {
            int j = str.indexOf("#x", curPos);
            if (j < 0) // no more #x
                curPos = str.length();
            else {
                int k = str.indexOf(';', curPos + 2);
                if (k < 0) // unterminated #x
                    curPos = str.length();
                else { // convert #xNNNN;
                    int n = Integer.parseInt(str.substring(j+2, k), 16);
                    char[] ch = { (char)n };
                    str = str.substring(0, j) + new String(ch) + str.substring(k+1);
                    curPos = j + 1; // after ch
                }
            }
        }
        return str;
    }

    static public void main(String... args) {
        String doc = "#xC1;o thun b#xE9; g#xE1;i c#x1ED9;t d#xE2;y xanh bi#x1EC3;n";
        System.out.println(convert(doc));
    }

}

除了假设字符是Unicode代码点而不是8859-1代码点之外,这与上一个答案的方法非常相似。

输出为

  

Áothunbégáicộtdâyxanhbiển

答案 1 :(得分:0)

Java中的字符串没有十六进制文字语法。如果需要支持该String格式,我将创建一个辅助函数,该函数将解析该格式并建立一个字节数组,然后将其解析为ISO-8859-1。

import java.io.ByteArrayOutputStream;

public class translate {

    private static byte[] parseBytesWithHexLiterals(String s) throws Exception {
        final ByteArrayOutputStream baos = new ByteArrayOutputStream();

        while (!s.isEmpty()) {
            if (s.startsWith("#x")) {
                s = s.substring(2);
                while (s.charAt(0) != ';') {
                    int i = Integer.parseInt(s.substring(0, 2), 16);
                    baos.write(i);
                    s = s.substring(2);
                }

            } else {
                baos.write(s.substring(0, 1).getBytes("US-ASCII")[0]);
            }

            s = s.substring(1);
        }

        return baos.toByteArray();
    }

    public static void main(String[] args) throws Exception {
        String doc = "#xC1;o thun b#xE9; g#xE1;i c#x1ED9;t d#xE2;y xanh bi#x1EC3;n";
        byte[] parsedAsISO88591 = parseBytesWithHexLiterals(doc);
        doc = new String(parsedAsISO88591, "ISO-8859-1");

        System.out.println(doc); // Print out the string, which is in Unicode internally.

        byte[] asUTF8 = doc.getBytes("UTF-8"); // Get a UTF-8 version of the string.
    }

}

答案 2 :(得分:0)

在这种情况下,代码确实可以掩盖要求。要求有些不确定,但似乎是要解码注释中记录的类似于HTML和XML的专用Unicode字符实体引用。

在某种程度上很少见的情况是,正则表达式引擎的优势胜过了解模式语言所需的任何学习。

String input = "#xC1;o thun b#xE9; g#xE1;i c#x1ED9;t d#xE2;y xanh bi#x1EC3;n";

// Hex digits between "#x" and ";" are a Unicode codepoint value
String text = java.util.regex.Pattern.compile("(#x([0-9A-Fa-f]+);)")
    .matcher(input)
    // group 2 is the matched input between the 2nd ( in the pattern and its paired )
    .replaceAll(x -> new String(Character.toChars(Integer.parseInt(x.group(2), 16))));
System.out.println(text);

matcher函数查找要替换的匹配模式的候选字符串。 replaceAll函数用计算出的Unicode代码点替换它们。由于Unicode代码点可能被编码为两个char(UTF-16)值,所以必须从char[]构造所需的替换字符串。