十六进制 - Java中的编码出错了

时间:2014-07-25 12:43:52

标签: java ascii

我和几位经验丰富的Java开发人员现在工作了1个小时,我们无法让它工作。有人对我有任何提示吗?

问题: 我们在Excel文件中得到一个文本,似乎编码完全不一致和愚蠢。有时会有特殊的字符,有时候不是,有时它们会以不同的方式显示和解释。

我现在要做的是编写一个Java脚本,检查Excel文件中的给定文本,并将所有不同的Char序列转换为我们想要的样式。

我的代码:

       while (iterator.hasNext()) {
            Entity entity = (Entity) iterator.next();
            Dataset dataset = produkt_store.getDataset(entity);
            FormData formdata = dataset.getFormData();
            DomElement dom = (DomElement) formdata.get(lang,
                    "cs_description_short").get();
            String beschreibung = dom.toText(true);

            System.out.println("Before: " + beschreibung);
            String hexBeschreibung = StringToHex(beschreibung);
            String newHexBeschreibung = hexBeschreibung.replaceAll("75 3F", "FC");
            newHexBeschreibung = newHexBeschreibung.replaceAll("75 A8", "FC");
            //beschreibung2 = beschreibung2.replaceAll("75A8", "FC");
            System.out.println("After: " + HexToString(newHexBeschreibung));
            System.out.println(hexBeschreibung.equals(newHexBeschreibung) + "\n");

            // dom.set(beschreibung);
        }

我还有那些函数来编码/解码为十六进制:

    private static String StringToHex(String s) {
        if (s.length() == 0)
            return "";
        char c;
        StringBuffer buff = new StringBuffer();
        for (int i = 0; i < s.length(); i++) {
            c = s.charAt(i);
            buff.append(Integer.toHexString(c) + " ");
        }
        return buff.toString().trim();
    }

    private static String HexToString(String s) {
        if (s.length() == 0)
            return "";
        String[] arr = s.split(" ");
        StringBuffer buff = new StringBuffer();
        int i;
        for (String str : arr) {
            i = Integer.valueOf(str, 16).intValue();
            String hs = new Character((char) i).toString();
            buff.append(hs);
        }
        return buff.toString();
    } 

示例:

有时候应该有一个“ü”它显示为“你?”我们显然想避免。在十六进制编辑器中查看它时,我们看到有时表示的那些东西 753F或75A8。 “ä”或“ö”或“ß”也是如此。所以即使是“你?”它从753F到有时75A8不等。我们试图用“ü”替换它。不行。有人有任何提示吗?

我们之前尝试使用String.replaceAll()并使用类似String.replaceAll(“u \?”,“ü”)的内容;但是,这根本没有改变,因为没有任何改变。

感谢有关该编码内容的任何提示! :)

编辑:

这是完美无缺的解决方案:

            beschreibung = beschreibung.replace("U\u0308", "\u00DC"); // "Ü"
            beschreibung = beschreibung.replace("u\u0308", "\u00FC"); // "ü"
            beschreibung = beschreibung.replace("A\u0308", "\u00C4"); // "Ä"
            beschreibung = beschreibung.replace("a\u0308", "\u00E4"); // "ä"
            beschreibung = beschreibung.replace("O\u0308", "\u00D6"); // "Ö"
            beschreibung = beschreibung.replace("o\u0308", "\u00F6"); // "ö"
            beschreibung = beschreibung.replace("s\u0308", "\u00DF"); // "ß"

2 个答案:

答案 0 :(得分:3)

某处有ü表示不是一个字符U-UMLAUT,而是SMALL-LETTER-U,其次是COMBING-DIACRITICAL-MARK-UMLAUT。这是有效的。

然后有一些转换回来,可能是ISO-8859-1(甚至是US-ASCII?),并且变音符号单独转换。 ISO-8859-1中没有这样的字符,而是你得到一个问号。

之后的修复将是:

String s = ...
s = s.replace("U?", "\u00DC")); // "Ü"
s = s.replace("u?", "\u00FC"); // "ü"
...

(我已经逃过了字符以防止可能有不同编码的java编译器和编辑器出现问题。(这将是一个错误。)

这也可以做得更复杂一些:

s = s.replaceAll("([aouAOU])\\?", "$1\u0308"); // Again ASCII + Umlaut separately
s = TextNormalizer.normalize(s, TextNormalizer.Form.NFC);
// Now single non-ASCII letters.

TextNormalizer可能是一个帮助。

警告:'?'也可以在控制台中显示(即从IDE中),因为也会发生转换。

某处转换已完成。这可以隐式发生,其中编码是可选的等等。您可以尝试将系统属性file.encoding设置为UTF-8或Cp1252(Windows Latin-1)。

答案 1 :(得分:0)

首先要检查的是:大/小写是否重要?例如如果你的toHex产生“75 3f”,你将不会用你给定的命令替换它。 hexBeschreibung = hexBeschreibung.toLowercase()可以解决这个问题。

第二:(更多提示)“你?”并不意味着'u' + '?',而是'u' + <not unicode character and definitly not '?'>

我希望我的第一个建议有所帮助:)

-
对不起,我无法评论,所以我要编辑:
十六进制编辑器可能会显示十六进制值大写或小写,因为它无关紧要。您必须自己检查已使用的String,因为Java可能在字符串中用小写字母表示十六进制。