如何在Perl中对JSON字符串进行诊断?

时间:2014-11-02 23:56:21

标签: json perl

我熟悉decode_json()函数,该函数尝试解码JSON字符串,如果不能这样做,则会错误地终止Perl程序 - 但这个问题关于该函数

我想要做的就是这个---我想要一个函数,通过它我可以运行一个JSON字符串,该函数只是告诉我JSON字符串是否是犹太教 - 如果它 isn&#39 ; t kosher,给我详细的信息它有什么问题。

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

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

如果 错误的字符串 - 我需要知道的不仅仅是错误,而是其中错误的字符串---包括将字符串解释为文件的完整内容时的行号。简而言之,这对于调试从中读取字符串的JSON文件非常有用。

3 个答案:

答案 0 :(得分:6)

decode_json()发生错误。如果需要以编程方式使用数据,可以通过包装eval或使用Try :: Tiny来捕获该错误。 croak错误消息显示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.

解密解码失败消息可能会令人沮丧。

这个很容易,因为我们知道它是由没有值的键引起的,所以解析器抱怨它没有找到它在char 19中预期的:。它还增加了有用的"之前"}"'帮助人们解释错误的信息。

有一种方法可以自动解析错误消息并显示更大的输入字符串块。

让我们快速转移python,json解析器是否提供了更有用的错误?不,它只显示char 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解析器还允许选择更轻松的翻译,例如将单引号(非法)解释为双引号(有效)。请参阅relaxedallow_singlequote选项。

也许你想要一个短片?

答案 1 :(得分: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";
}

答案 2 :(得分:0)

6 年后......

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

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

它测试给定的 json 字符串是否是有效的 json。如果没有……您可以使用其他人在此处建议的 jslinter 选项来了解原因,否则您可以安全地继续前进。

祝你好运