【问题标题】:Parsing Quoted Strings Having Nested Escape Sequences in jsoncpp在 jsoncpp 中解析具有嵌套转义序列的引用字符串
【发布时间】:2015-12-04 08:47:11
【问题描述】:

我在这里使用jsoncpp 库。我对单引号 (') 和双引号 (") 的解析感到困惑。

Json::Value root;
Json::Reader reader;
const std::string json_str1 = "{\"name\":\"Say \\\"Hello\\\"!\"}";
const std::string json_str2 = "{\"name\":\"Say \"Hello\"!\"}";
const std::string json_str3 = "{\"name\":\"Say \\\'hi\\\'!\"}";
const std::string json_str4 = "{\"name\":\"Say \'hi\'!\"}";
const std::string json_str5 = "{\"name\":\"Say 'hi'!\"}";
reader.parse(json_str1, root, false);   // success
reader.parse(json_str2, root, false);   // fail
reader.parse(json_str3, root, false);   // fail
reader.parse(json_str4, root, false);   // success
reader.parse(json_str5, root, false);   // success

为什么双引号必须像\\\",而单引号必须是\'或只是',但不能是\\\'

【问题讨论】:

    标签: c++ json string escaping jsoncpp


    【解决方案1】:

    转义分隔符

    使用\ 转义引号的原因是为了让解析器能够区分旨在作为引用字符串中的字符的引号和旨在关闭引号的定界引号。字符串。

    如您所知,在 C++ 语言中,双引号 " 用于分隔字符串。但是如果你想创建一个包含双引号"的字符串,\被用作转义符,因此C++解析器知道将以下字符解释为字符,不作为结束分隔符:

    const std::string double_quote = """;     // WRONG!
    


    const std::string double_quote = "\"";    // good
    


    有两个解析器

    在您的代码中,涉及两个解析器:作为将编译此代码的 C++ 编译器的一部分的 C++ 解析器,以及作为 jsoncpp 库的一部分的 JSON 解析器。 C++ 解析器在编译时解释此代码,而 jsoncpp 解析器在运行时解释字符串。

    与 C++ 一样,JSON 也使用双引号 " 来分隔字符串。 jsoncpp 解析器看到的简单 JSON 文档看起来像这样:

    {"name":"Xiaoying"}
    

    要将此 JSON 文档包含在 C++ 字符串中,JSON 文档中的双引号 " 需要使用 \ 进行转义,如下所示:

    const std::string json_name = "{\"name\":\"Xiaoying\"}";    // good
    

    这告诉 C++ 创建一个内容为{"name":"Xiaoying"} 的字符串。

    嵌套分隔符

    当 JSON 文档本身包含也必须转义的分隔符时,事情开始变得复杂。与 C++ 一样,JSON 也使用反斜杠 \ 作为转义。现在问题变成了,如何区分用于 jsoncpp 解析器转义的反斜杠 \ 和用于 C++ 解析器转义的反斜杠 \?执行此操作的方法是使用 双反斜杠 \\ 序列,该序列由 C++ 解析器转换为字符串中的单个反斜杠 '\' 字符。该单个反斜杠在运行时传递给 jsoncpp 解析器时,将被解释为转义字符。

    由于 JSON 中反斜杠的使用规则与 C++ 的规则不同,事情变得更加复杂。特别是,在 C++ 中,单引号 ' 可以用反斜杠转义(如 \'),但这不是 JSON 中的合法模式。

    以下是您提出的五个案例的解释:

    1. json_str1

    C++ 语句

    const std::string json_str1 = "{\"name\":\"Say \\\"Hello\\\"!\"}";
    

    生成一个看起来像这样的 JSON 文档

    {"name":"Say \"Hello\"!"}
    

    当 jsoncpp 解析器看到这个时,它会通过反斜杠知道 "Say \"Hello\"!" 表示这是一个包含 Say "Hello"! 的字符串

    2。 json_str2

    C++ 语句

    const std::string json_str2 = "{\"name\":\"Say \"Hello\"!\"}";
    

    生成一个看起来像这样的 JSON 文档

    {"name":"Say "Hello"!"}
    

    由于"Hello"周围的引号没有转义,所以jsoncpp解析器会失败。

    3. json_str3

    C++ 语句

    const std::string json_str3 = "{\"name\":\"Say \\\'hi\\\'!\"}";
    

    生成一个看起来像这样的 JSON 文档

    {"name":"Say \'hi\'!"}
    

    由于\' 模式在 JSON 中不被识别,这将在 jsoncpp 解析器中失败。

    4. json_str4

    C++ 语句

    const std::string json_str4 = "{\"name\":\"Say \'hi\'!\"}";
    

    生成一个看起来像这样的 JSON 文档

    {"name":"Say 'hi'!"}
    

    这是因为 C++ 解析器将 \' 序列解释为单个 ' 字符。

    5. json_str5

    C++ 语句

    const std::string json_str5 = "{\"name\":\"Say 'hi'!\"}";
    

    生成一个看起来像这样的 JSON 文档

    {"name":"Say 'hi'!"}
    


    另见

    对于 C++ 转义序列规则:http://en.cppreference.com/w/cpp/language/escape

    对于 JSON 转义序列规则:http://www.json.org/


    【讨论】:

    • 谢谢!这个答案很有帮助。另外,如果我想要一个 JSON 文档,看起来像 {"date": "9/4"}。 C++ 语句可能类似于{"\date\":\"9\\/4\"}"。但是{"\date\":\"9\\\/4\"}" 会引发 unknown escape sequence: '\/' 警告。是不是因为\/ 是 JSON 转义序列而不是 C++ 转义序列?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-27
    • 1970-01-01
    • 1970-01-01
    • 2020-02-19
    • 2016-02-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多