“org.apache.commons.lang.StringEscapeUtils”和“en dash”

时间:2011-02-16 14:30:52

标签: java unicode character-encoding html-escape-characters

我正在使用“* org.apache.commons.lang.StringEscapeUtils.unescapeHtml(myHtmlString)”将Html实体转义符转换为包含与转义符对应的实际Unicode字符的字符串。但是它没有正确解析“em dash”和“en dash”符号。 StringEscapeUtils将“ - ”替换为“\ u0096”,而正确的错位是“\ u2013”​​。正如我所读到的“\ u0096”是cp1252相当于“ - ”。那么我怎样才能让它以正确的方式运作呢?我知道我可以手动替换它,但我想知道我是否可以使用StringEscapeUtils或任何其他工具来实现。

2 个答案:

答案 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")读取/解码它。