HJSON 只会解析整数或 'null' 值

HJSON Will Only Parse Integers or 'null' Values

我正在尝试将应该 JSON 的内容解析为 Python 字典。但是,我正在使用的 JSON 文件无效 JSON,因为键值对周围经常会缺少引号。 HJSON 似乎是我要找的东西,但是如果我尝试传递 null 或任何整数以外的任何值,我发现它会出错。

使用我必须使用的一些 'JSON' 值来尝试它:

import hjson

# EXAMPLE 1
working = hjson.loads('{ date_closed: null }')  # <- THIS WORKS!
print(working)
OrderedDict([('date_closed', None)])

# EXAMPLE 2
works_too = hjson.loads('{ date_closed: 42 }')  # <- THIS WORKS!
print(works_too)
OrderedDict([('date_closed', 42)])

# EXAMPLE 3
not_working = hjson.loads('{ date_closed: yes }')  # <- ERRORS!

~/hjson/decoder.py in scanKeyName(s, end, encoding, strict)
    278 
    279         if ch == '':
--> 280             raise HjsonDecodeError("Bad key name (eof)", s, end);
    281         elif ch == ':':
    282             if begin == end:

HjsonDecodeError: Bad key name (eof): line 1 column 21 (char 20)

# EXAMPLE 4
# Using different key name
also_not_working = hjson.loads('{ date_opened: yes }')  # <- ERRORS with identical error message as above

# Different value name, showing it's not a 'key' error but a 'value' error
this_works = hjson.loads('{ date_opened: null }') # <- THIS WORKS!
print(this_works)
OrderedDict([('date_opened', None)])


# EXAMPLE 5
doesnt_work = hjson.loads('{ date_opened: None }')  # <- ERRORS with identical error message as above

  1. 错误信息似乎不正确。有问题的不是 key name(因为同一个键有时会起作用),而是 value name.

  2. 似乎能够被 HJSON 解析的唯一值是整数(值 42 有效)和 null 值。

我在这里错过了什么?

我只是在摆弄这个并查看 HJSON spec, and based on the examples under there (also under the try 部分),相信我已经弄明白了。它没有明确解释,如果我错了,有人可以纠正我,但看起来 HJSON 需要左大括号和右大括号,{} 在不同的行上;至少,这就是我认为 Python 实现所坚持的,无论如何。例如,这是一个简单的用法,我能够确认它似乎可以毫无问题地解析:

print(hjson.loads('''
{
  testing_123: hello world
}
'''))

# now it works! prints out:
#   OrderedDict([('testing_123', 'hello world')])

所以在你的情况下,我想最简单的修复方法(也就是说,如果你不想手动将大括号放在不同的行上)是创建一个包装函数 loads,定义如下:

import hjson


def loads(string, decoder=hjson.loads):
    return decoder(string.replace('{', '{\n').replace('}', '\n}'))

现在,我可以确认上面的两种情况现在似乎都按照最初的预期进行了解析:

working_now = loads('{ date_closed: yes }')
print(working_now)

also_working = loads('{ date_opened: yes }')  # <- ERRORS with identical error message as above
print(also_working)

输出:

OrderedDict([('date_closed', 'yes')])
OrderedDict([('date_opened', 'yes')])