Java XML:如何逃避'&',但跳过'&'

时间:2014-06-21 09:09:04

标签: java xml

我需要逃避'&',但跳过&

我使用下一个功能

public static String translateAll(String input, String[] patterns, String[] replacements) {
    String result = input;

    for (int i = 0; i < patterns.length; i++) {
        result = result.replaceAll(patterns[i], replacements[i]);
    }

    return result;
}

...

private static final String[] decoded = { "&", "<", ">", "\"", "\'" };
private static final String[] encoded = { "&amp;", "&lt;", "&gt;", "&quot;", "&apos;" };

public static String escape(String input) {
    return translateAll(input, decoded, encoded);
}

...

String escapedBodyValue = XMLUtils.escape(originBodyValue);

它取代了所有&amp;与&amp; 但它也会用&amp;

替换所有&amp;amp;

那么,如何跳过已经转义的字符?

6 个答案:

答案 0 :(得分:6)

不要这样做。你只是破坏了比现在更多的东西......在1小时内,你会发现你的方法也用&quot;替换了&amp;quot;,你需要再做一次黑客......

你的逃跑显然已经 已经被破坏了。不要使用字符串替换来破坏它,但尝试解析数据回到所谓的意味着什么,然后使用正确的编码器产生正确转义的版本。

简而言之:永远不会使用println来生成XML 。使用执行转义的XML生成器。

另见着名的 StackOverflow问题/答案:https://stackoverflow.com/a/1732454/1060350

答案 1 :(得分:3)

你的输入搞砸了。我会将 unescaping 一切都考虑为“正常形式”,&<>未转义,然后转义结果。使用StringEscapeUtils(来自Apache Commons lang)看起来像这样:

String test = "aaa &amp; bbb & ccc &lt; ddd & eee.";
test = StringEscapeUtils.escapeXml(StringEscapeUtils.unescapeXml(test));

结果:

aaa &amp; bbb &amp; ccc &lt; ddd &amp; eee.

如果您真的想继续使用当前的解决方案,我建议您使用以下内容:

test = test.replaceAll("&(?!.{2,4};)", "&amp;");

正则表达式的细分:

  • & - &个字符
  • (?! ___ ) - 未跟___
  • .{2,4} - 任意2,3或4个字符
  • ; - 后跟;

答案 2 :(得分:2)

这有点像kludge,但我只是做你目前正在做的事情,然后将所有&amp;amp;替换为&amp;(以及其他如&amp;lt;&lt; 1}}),直到不再需要更改为止所需的次数。

答案 3 :(得分:1)

我认为这种模式会让你感受到每一个&#34;&amp;&#34;没有跟随amp haha​​

&(?!(amp))

答案 4 :(得分:0)

你可能会想出一个疯狂的正则表达式来取代单个特殊字符,而不是字符引用。请注意,您还可以拥有实体引用和&xxxx;序列(遵循@Edward M.B.建议它可以像&(?!([0-0a-zA-Z]+;))一样简单。)

如果它不起作用,你可以编写自己的函数,在找到'&amp;'之后预读,缓冲,并累积字母数字字符直到';'满足(此时你转储缓冲区),或满足非字母数字字符,此时你转储'&amp;'和第一个字符以外的缓冲区。

但是,您的问题显示的是,您正在混合不应混合的字符数据。正确的方法是永远不要使用半编码的字符串,并确保您处理完全编码或完全原始数据。

答案 5 :(得分:0)

刚刚用过它,效率不是很高,但它是一种方式

String test = "testin & with testing &amp;" 
test = test.replace("&", "&amp;");
test = test.replace("&amp;amp;", "&amp;");