如何HTML转义Java字符串中的卷曲引号

时间:2009-11-13 21:04:08

标签: java unicode html-entities

我有一个带有卷曲引号的字符串。我想用HTML实体替换它们,以确保它们不会混淆其他下游系统。对于我的第一次尝试,我只是添加了我想替换的字符的匹配,直接在我的代码中输入:

public static String escapeXml(String s) {
    StringBuilder sb = new StringBuilder();
    char characters[] = s.toCharArray();
    for ( int i = 0; i < characters.length; i++ ) {
        char c = characters[i];
        switch (c) {
            // other escape characters deleted for clarity
            case '“':
                sb.append("&#8220;");
                break;
            case '”':
                sb.append("&#8221;");
                break;
            case '‘':
                sb.append("&#8216;");
                break;
            case '’':
                sb.append("&#8217;");
                break;
            default:
                sb.append(c);
                break;
        }
    }
    return sb.toString();
}

这在我的Mac上编译并运行良好,但是当我们的CI服务器(在Linux上运行)试图构建它时,它会窒息:

Out.java:[347,16] duplicate case label

显然,Linux机器上的构建链的某些部分无法识别和区分这些花哨的字符。

我的下一次尝试是使用Unicode转义。不幸的是,这甚至都不能在我的Mac上编译:

...
            case '\u8220':
                sb.append("&#8220;");
                break;
            case '/u8221':
                sb.append("&#8221;");
                break;
...

我的编译器抛出了这个抱怨:

Out.java:[346,21] unclosed character literal

我感到困惑的是,人们可以如何进行这种替换并使其在各种平台上可靠地运行。有没有人有指针?提前谢谢。

5 个答案:

答案 0 :(得分:4)

Unicode文字是十六进制的:

case '\u201c':
    sb.append("&#8220;");
    break;
....

而且,正如其他答案中所提到的,你的一个文字中有一个/而不是\

答案 1 :(得分:4)

您可以使用文字字符(即'‘'),但您的构建过程需要在编译期间指定正确的源编码。 javac命令选项为-encoding。 (Ant的javac任务上的属性是相同的。)这应该与保存文件时IDE使用的任何编码相匹配。

例如,如果您的IDE使用UTF-8,但构建计算机使用其平台默认编码US-ASCII,则特殊字符将解码为?。由于现在多个案例具有相同的标签,因此您会收到原始错误消息。

答案 2 :(得分:3)

编译问题是因为你有'/ u8221'而不是'\ u8221' - 正斜杠而不是反斜杠。

我并不完全相信使用这些实体会有所帮助,但你可以试试......我想这取决于下游代码的破坏程度。

编辑:Doh,我没有发现你的Unicode值是十进制的。是的,他们需要十六进制:)我会在这里留下这个答案,因为它解释了为什么编译器在抱怨 - '\ u8221'是一个完美的字符转义序列,而不是你想要的那个:)

答案 3 :(得分:0)

默认编码因平台而异--Windows使用自己的ISO-Latin-1方言(至少是我所使用过的方言)。 Linux经常使用UTF-8(这很可能是你的问题)而Mac使用MacRoman。您可以通过保持简单的7位ASCII来避免大多数问题,如果您需要在源代码中使用\ u,则可以使用\ u。

就个人而言,我会在Java源代码之外保留“国家”,并使用本地化功能查找已翻译的字符串以获取简单的密钥,并将 放在Java代码中。

答案 4 :(得分:0)