我正在使用“* org.apache.commons.lang.StringEscapeUtils.unescapeHtml(myHtmlString)”将Html实体转义符转换为包含与转义符对应的实际Unicode字符的字符串。但是它没有正确解析“em dash”和“en dash”符号。 StringEscapeUtils将“ - ”替换为“\ u0096”,而正确的错位是“\ u2013”。正如我所读到的“\ u0096”是cp1252相当于“ - ”。那么我怎样才能让它以正确的方式运作呢?我知道我可以手动替换它,但我想知道我是否可以使用StringEscapeUtils或任何其他工具来实现。
答案 0 :(得分:1)
And as I have read "\u0096" is cp1252 equivalent for "–".
我不这么认为。 Unicode中的0x0096是C1控制代码:
http://en.wikipedia.org/wiki/C0_and_C1_control_codes
并且不太可能是“ - ”的替代品(如你所写)。
好吧,如果 StringEscapeUtils 真的搞砸了这一点(确实应该是\ u2013),如果它是唯一的逃脱,它就会搞乱,如果没有理由在你的字符串中有任何其他的0x0096 ,然后替换所有 之后调用 StringEscapeUtils 应该有效。
以下是你期望的替换:
System.out.println("Broken\u0096stuff".replaceAll("\u0096", "\u2013"));
但是,您应该首先确保 StringEscapeUtils 真的搞砸了,真的,真的,理解为什么/如何在Java String中获得0x0096。
然后,也应该向你指出,遗憾的是Java的Unicode支持是一个主要的SNAFU,因为Java是在Unicode 3.1出现之前构思的。
因此,对于 char 原语使用16位似乎是一个明智的想法,使用4-hexdigits'\ uxxxx'转义序列似乎是一个明智的想法,它似乎是一个聪明的想法来表示String的length()方法中 char [] 的长度等。
这些实际上都是非常非常愚蠢的想法导致其中一个主要的Java SNAFU,其中 char 原语实际上不能再保存Unicode字符,并且String的长度方法实际上不返回String的实际长度。
我喜欢以下内容:
final char brokenCharCannotRepresentUnicode31Codepoints = '\uFFFF'; // How do I store a Unicode 3.1 codepoint here!?
为什么这个咆哮?好吧,因为我不知道String的 replaceAll 中的regexp替换是如何实现的,但是如果有的话,我真的就不会感到惊讶( ie 某些代码点)String的 replaceAll 就像 char 一样, length ,就像 \ uxxxx 一样。嗯,完全坏了。
答案 1 :(得分:1)
我怀疑问题不在StringEscapeUtils.unescapeHtml(...)
电话中。
相反,我怀疑该字符在调用之前已被转换为'\u0096'
。更具体地说,我怀疑在将HTML作为字符读取时,您的代码使用了错误的字符集。
正如你所说,en-dash是cp1252中的代码点0x96
。因此,获取en-dashed错误转换为unicode代码点\u0096
的一种方法是从使用cp1252编码的字节流开始,并使用InputStreamReader(is, "Latin-1")
读取/解码它。