2

我正在尝试将应该是 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值。

我在这里想念什么?

4

1 回答 1

1

我只是在摆弄这个并查看HJSON 规范,并根据那里的示例(也在尝试部分下),相信我已经弄清楚了。它没有这样清楚地解释,如果我错了,有人可以纠正我,但看起来 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')])
于 2021-11-27T04:14:11.257 回答