解析某网站的API
数据,该数据表面上以JSON
形式返回,实际上像是人工直接拼接而成,如:
<?php
$chapters = ['第一章 开始', '第二章 过程', '第三章 结束'];
echo '[';
foreach ($chapters as $id => $name)
echo '{"id":' . $id . ',"name":"' . $name . '"},';
echo ']';
[{"id":0,"name":"第一章 开始"},{"id":1,"name":"第二章 中间"},{"id":2,"name":"第三章 结束"},]
大部分时候问题不大(处理末尾逗号即可),但出错的时候是真的棘手。搜集了一些出错的例子(简化):
[
{"name": "第五卷:"世家"子弟"}, # 这种情况出现最多,没转义『"』
{"name": "天下大乱(上)【\x06】"}, # 出现了 ASCII 0-31 的字符,json 规范是不允许的
{"name": "\"小白兔\"少爷"}, # 转义了不该转义的字符
{"name": "番外篇~\(≧▽≦)/~"}, # 同上
{"name": "权力的Chun\药"}, # 同上
{"name": 饮马江湖"}, # 搞不明白这是怎么出现的。是标题含有“退格符”(\x08),吃掉上一个『"』吗?
{"name": style="color:Gray;"}, # ???
{"name": ""}, # 最后一项末尾不能有『,』
]
我觉得正则规范它们可能是开发/运行效率最高的一个
自己写解析器,怕又慢又不保证正确
去除末尾逗号的正则,我已经写了(前提是其他内容都是正确的)
模式:("(?:\\?.)*?")|,\s*([]}])
替换:\1\2
截取?
说起这个json,我原生js获取正常,拿这个uniapp写,搞了一天都没解析成,睡前搜到了几篇文章,明天看看
@20263,@无名啊,@淡然,当然对于引号不匹配这种问题,eval也无能为力,也只会得到错误。此时,如果想可靠地提取信息,可以考虑放弃格式分析,直接进行正则表达式内容匹配:
var json = `[
{"name": "第五卷:"世家"子弟"}, # 这种情况出现最多,没转义『"』
{"name": "天下大乱(上)【\x06】"}, # 出现了 ASCII 0-31 的字符,json 规范是不允许的
{"name": "\"小白兔\"少爷"}, # 转义了不该转义的字符
{"name": "番外篇~\(≧▽≦)/~"}, # 同上
{"name": "权力的Chun\药"}, # 同上
{"name": 饮马江湖"}, # 搞不明白这是怎么出现的。是标题含有“退格符”(\x08),吃掉上一个『"』吗?
{"name": style="color:Gray;"}, # ???
{"name": ""}, # 最后一项末尾不能有『,』
]`;
var results = json.matchAll(/\{"name":\s*"?(.*?)"?\},/gm);
for (var obj of results) {
console.log(obj[1]);
}
PHP版:
<?php
$json = <<<EOF
[
{"name": "第五卷:"世家"子弟"}, # 这种情况出现最多,没转义『"』
{"name": "天下大乱(上)【\x06】"}, # 出现了 ASCII 0-31 的字符,json 规范是不允许的
{"name": "\"小白兔\"少爷"}, # 转义了不该转义的字符
{"name": "番外篇~\(≧▽≦)/~"}, # 同上
{"name": "权力的Chun\药"}, # 同上
{"name": 饮马江湖"}, # 搞不明白这是怎么出现的。是标题含有“退格符”(\x08),吃掉上一个『"』吗?
{"name": style="color:Gray;"}, # ???
{"name": ""}, # 最后一项末尾不能有『,』
]
EOF;
preg_match_all('/\{"name":\s*"?(.*?)"?\},/m', $json, $results, PREG_SET_ORDER);
foreach ($results as $obj) {
echo $obj[1], "\n";
}
@幕后导演,@老虎会游泳,我改下措辞,这是某网站的APP
客户端的API
数据,应该不是在浏览器内解析的
上述例子的真实链接:
先求助万能虎,@老虎会游泳
有没有可能用正则规范它们