我和几位经验丰富的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"); // "ß"
答案 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可能在字符串中用小写字母表示十六进制。