解析jsoncpp中嵌套转义序列的带引号字符串

Parsing Quoted Strings Having Nested Escape Sequences in jsoncpp

本文关键字:字符串 转义序列 jsoncpp 嵌套 解析      更新时间:2023-10-16

我在这里使用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++语言中,双引号"用于分隔字符串。但是,如果要创建一个包含双引号"的字符串,将用作转义符,因此C++解析器知道将以下字符解释为字符,而不是结束分隔符:

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


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


带有两个解析器

在您的代码中,有两个解析器:C++解析器和JSON解析器,前者是编译此代码的C++编译器的一部分,后者是jsoncpp库的一部分。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++中,单引号"0可以用反斜杠转义(如'),但这不是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/