为什么GSON将“\ n”和“\\ n”解析为换行符?

时间:2017-06-26 16:18:12

标签: java json parsing gson

我有以下代码:

public static void main(String[] args) {
    String key = "myjsonkey";
    String baseJson = "{\"" + key + "\":\"my json %svalue\"}";

    String inBackslashAndN = String.format(baseJson, "\\n");
    String inNewline = String.format(baseJson, "\n");

    String outBackslashAndN = valueFromJson(key, inBackslashAndN);
    String outNewLine = valueFromJson(key, inNewline);

    System.out.print("\nInput strings matching: ");
    System.out.println(inBackslashAndN.equals(inNewline));
    System.out.print("Output strings matching: ");
    System.out.println(outBackslashAndN.equals(outNewLine));
}

private static String valueFromJson(String key, String jsonStr) {
    System.out.println("\nINPUT: " + jsonStr);
    JsonObject json = new JsonParser().parse(jsonStr).getAsJsonObject();
    String output = json.get(key).getAsString();
    System.out.println("\nOUTPUT: " + output);
    return output;
}

输出:

INPUT: {"myjsonkey":"my json \nvalue"}

OUTPUT: my json 
value

INPUT: {"myjsonkey":"my json 
value"}

OUTPUT: my json 
value

Input strings matching: false
Output strings matching: true

我的问题是:为什么JSON将“\ n”和“\\ n”解析为换行符,是否有办法强制对这两者进行不同的解析而不更改原始数据?

我正在使用gson 2.7

编辑:我知道“\ n”被处理成新的行控制字符,“\\ n”是字符'反斜杠'和Java中的字符'n'的序列。我的问题仍然存在。

3 个答案:

答案 0 :(得分:2)

JSON不支持字符串中的文字换行符。来源:http://json.org/

换行符必须表示为\n。 GSON很可能接受已经转义的斜杠+ n或文字换行符,并在JSON表示中标准化为斜杠+ n,当转换回字符串时,再次将斜杠+ n解析为文字换行符。

答案 1 :(得分:0)

\n是换行控制字符,\\n有两个字符,反斜杠和字母n。

这两种情况都插入了JavaScript字符串" ..."。因此第二个版本将转换为换行符。显然,对于第一种情况,字符串中的换行字符是允许的。

答案 2 :(得分:0)

  

为什么JSON解析" \ n"和" \ n"作为换行线?

\n被处理为实际的文字换行符(即Unicode 000A)。 \\n相当于字符串" \ n" JSON解析器(正确地)将其解析为换行符" \ n"是JSON中的换行符。如果您想要实际的" \ n",则可能需要\\\\n。请参阅JSON.org,转义序列位于" char"右侧。当您最终使用多种语言(例如Java + Regex / JSON)进行操作时,您往往会遇到一些混乱的转义序列嵌套。

JSON本身在技术上也不支持字符串中的换行符。不过,Gson通过将其转换为" \ n"来解决这个问题:

enter image description here

  

有没有办法在不改变原始数据的情况下强制对这两者进行不同的解析?

我认为Gson没有提供这样做的方法,根据JSON标准,它没有多大意义。你可以:

String unescaped = myString.replace("\\", "\\\\");

或使用正则表达式:

String unescaped = myString.replaceAll("\\\\", "\\\\\\\\");