如何在 Perl 中验证 JSON?

问题描述 投票:0回答:3

我熟悉

decode_json()
函数,它尝试解码 JSON 字符串,如果失败,则会错误地终止 Perl 程序,但这个问题不是关于该函数。

我想做的是这样的——我想要一个函数,通过它我可以运行 JSON 字符串,该函数会简单地告诉我 JSON 字符串是否是 kosher 的——如果它 不是 kosher,请给我 详细信息有什么问题。

有这样的功能吗?如果是这样,这里有人可以给我指出正确的方向吗?

该函数不需要需要解码 JSON 字符串 - 它只需要通知调用程序是否可以解码 JSON 字符串 - 并允许调用程序继续运行,无论结果如何。

如果字符串出现

问题 - 我需要知道的不仅仅是错误的种类,而是字符串中的错误所在,包括如果字符串被解释为什么行号文件的全部内容。简而言之,这些信息对于调试从中读取字符串的 JSON 文件很有用。

json perl
3个回答
10
投票

decode_json()

 出错时发出嘎嘎声。  如果您需要以编程方式使用数据,您可以通过包装 
eval
 或使用 Try::Tiny 来捕获该错误。  呱呱的错误消息显示了 json 解析器失败的地方。

$perl_scalar=decode_json $json_text

encode_json 相反:需要一个 UTF-8(二进制)字符串,并尝试将其解析为 UTF-8 编码的 JSON 文本,返回结果引用。出错时发出嘎嘎声。

http://search.cpan.org/~mlehmann/JSON-XS-3.01/XS.pm#FEATURES

#!/usr/bin/env perl use JSON qw(decode_json); my $maybe_json = '{"foo":"bar", "baz"}'; # invalid, baz key is missing value my $json_out = eval { decode_json($maybe_json) }; if ($@) { print "decode_json failed, invalid json. error:$@\n"; }
产生:

decode_json failed, invalid json. error:':' expected, at character offset 19 (before "}") at ./foo.pl line 6.
破译解码失败消息可能非常困难。

这个很简单,因为我们知道它是由没有值的键引起的,所以解析器抱怨它没有找到它在字符 19 处期望的

:

。它还添加了有用的 'before "}"'帮助人们解释错误的消息。

如果有一种方法可以自动解析错误消息并显示更大的输入字符串块,那就太好了。

让我们快速进行一下Python转换,那个json解析器是否提供了更有用的错误? 不,它只显示字符 19,甚至没有“before }”上下文。

>>> import json >>> maybe_json = '{"foo":"bar", "baz"}' >>> json.loads(maybe_json) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/Users/andrew/anaconda/lib/python2.7/json/__init__.py", line 338, in loads return _default_decoder.decode(s) File "/Users/andrew/anaconda/lib/python2.7/json/decoder.py", line 365, in decode obj, end = self.raw_decode(s, idx=_w(s, 0).end()) File "/Users/andrew/anaconda/lib/python2.7/json/decoder.py", line 381, in raw_decode obj, end = self.scan_once(s, idx) ValueError: Expecting : delimiter: line 1 column 20 (char 19)
那么,最终的答案是什么?  json 解析器规范非常简单,如果出现错误就会退出。  调用解析器,如果成功则字符串有效,否则向用户显示它死在哪里并询问该怎么做。  Perl 的 json 解析器还允许选择更宽松的翻译,例如将单引号(非法)解释为双引号(有效)。  请参阅 

relaxed

allow_singlequote
 选项。

也许你想要一个短绒棉?


1
投票
这称为“linting”。 CPAN 上有一个非常好的 JavaScript Linter 包:

JavaScript::JSLint



来自文档;

use JavaScript::JSLint; my @errors = jslint($javascript); for my $err (@errors) { print "$err->{reason} at line $err->{line}\n"; }
    

1
投票
6年后......

这可能就是您正在寻找的答案:

https://metacpan.org/pod/Test::JSON

它测试给定的 json 字符串是否是有效的 json。如果没有......您可以使用其他人在这里建议的 jslinter 选项来获取不这样做的原因,但否则您可以安全地继续前进。

祝你好运

© www.soinside.com 2019 - 2024. All rights reserved.