在 jsoncpp 中解析具有嵌套转义序列的引用字符串
Parsing Quoted Strings Having Nested Escape Sequences in jsoncpp
我在这里使用 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++ 解析器是将编译此代码的 C++ 编译器的一部分,JSON 解析器是 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++ 中,单引号 '
可以用反斜杠转义(如 \'
),但这在 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/
我在这里使用 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++ 解析器是将编译此代码的 C++ 编译器的一部分,JSON 解析器是 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++ 中,单引号 '
可以用反斜杠转义(如 \'
),但这在 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/