最可靠的方式是使用 jsoncpp 尝试解析并捕获异常:配置 Json::CharReaderBuilder 为宽松模式,调用 Json::parseFromStream 解析字符串,解析成功后用 root.isArray() 判断是否为数组类型。

用 jsoncpp 解析并捕获异常来判断是否为合法 JSON 数组
最可靠的方式不是“校验字符串结构”,而是尝试解析——JSON 格式有严格语义,仅靠正则或首尾字符(如 [ 和 ])无法覆盖嵌套、转义、空格、数值边界等所有情况。用成熟解析器解析失败即说明非法。
以 jsoncpp 为例,需确保:Json::CharReaderBuilder 配置为宽松模式(允许尾部空白),且明确检查解析后对象类型是否为 array:
#include <json/json.h>
#include <sstream>
bool is_valid_json_array(const std::string& s) {
Json::CharReaderBuilder builder;
builder["collectComments"] = false;
JSONCPP_STRING errs;
std::istringstream iss(s);
Json::Value root;
if (!Json::parseFromStream(builder, iss, &root, &errs)) {
return false; // 解析失败,非合法 JSON
}
return root.isArray(); // 必须是数组类型,而非只是以 [ 开头的 JSON 对象
}
- 必须调用
root.isArray(),不能只检查s[0] == '['——例如"[1,2]"是数组,但"{ "a": [1,2] }"是对象,也含方括号 -
Json::parseFromStream比parseFromValue更健壮,能处理 BOM 和流末尾多余空白 - 若传入空字符串、
null、123或{},root.isArray()均返回false
不用第三方库时,最小化预检 + std::from_chars 辅助验证
若项目禁止引入 jsoncpp 或 nlohmann/json,可做轻量级预筛,但仅适用于可信输入或性能敏感的粗筛场景——它不保证 100% 正确,仅排除明显非法格式。
关键点:合法 JSON 数组必须以 [ 开始、以 ] 结束,中间可含空白、元素、逗号,且不能出现未闭合引号或非法控制字符:
立即学习“C++免费学习笔记(深入)”;
详细的 Three.js 3D 图形参考,涵盖场景设置、相机、几何体、材质、光照、动画、控制器、加载器、数学工具和调试。
- 先 trim 首尾空白(用
std::isspace判断) - 检查首字符是否为
'[',末字符是否为']'(注意:末字符需跳过末尾空白) - 简单计数引号和括号嵌套:遇到
"切换字符串模式;在非字符串模式下,[/{递增深度,]/}递减;深度不能为负,结束时深度必须为 0 - 对数组内每个逗号分隔的子串(需跳过引号内逗号),可尝试用
std::from_chars检查是否为纯数字(非必需,仅辅助)
这种逻辑易漏掉 "["\"]"(合法含转义引号)或 "[true,null,{}]",所以仅建议用于日志行快速过滤,不可替代真实解析。
nlohmann/json 的写法更简洁,但要注意异常类型
若已使用 nlohmann/json,判断逻辑极简,但必须捕获正确的异常——json::parse_error 表示语法错误,而 json::type_error 可能在访问时抛出(如把对象当数组用):
#include <nlohmann/json.hpp>
using json = nlohmann::json;
bool is_valid_json_array(const std::string& s) {
try {
json j = json::parse(s);
return j.is_array();
} catch (const json::parse_error&) {
return false;
}
}
- 不要忽略
json::invalid_iterator等其他异常——实际中极少触发,但若输入含 u 编码错误,可能抛json::type_error -
j.is_array()在空数组[]、含布尔/字符串/嵌套数组的[1,"a",[]]下均返回true - 该库默认拒绝尾部多余字符(如
"[1,2]"xxx),符合 JSON RFC 严格要求
常见误判场景和调试建议
很多看似“应该合法”的字符串会被拒绝,原因常被忽略:
-
"[1, 2,]":末尾多余逗号——JSON 标准不允许,jsoncpp和nlohmann均报错 -
"[1,2,3 ]":换行符本身合法,但若混用且解析器未设 UTF-8 模式,可能因 BOM 解析失败 -
"[1,2,3] ":末尾空格——jsoncpp默认接受,nlohmann也接受;但若用std::stringstream构造流时未设置std::ios::skipws,可能提前截断 -
"["hello\"]":反斜杠未正确转义——C++ 字符串字面量中需写成"["hello\\"]"才能传给解析器真正的"["hello\"]"
调试时优先打印原始字节(用 for (auto b : s) printf("%02x ", (unsigned char)b);),比肉眼读字符串更可靠——尤其当遇到不可见控制字符或编码混淆时。

















