将前导零整数转换为json

时间:2019-02-14 11:31:29

标签: python json regex

我使用json-library将字符串转换为json对象:

a = '{"index":1}'
import json
json.loads(a)
{'index': 1}

但是,如果我改为将字符串a更改为包含前导0,则它会分解:

a = '{"index":01}'
import json
json.loads(a)
>>> JSONDecodeError: Expecting ',' delimiter

我认为这是由于以下事实造成的:如果thread中所述的整数以前导零开头,则它是无效的JSON。

有没有办法解决这个问题?如果不是,那么我猜最好的方法是先从字符串中删除一个正则表达式中的前导零,然后转换为json?

3 个答案:

答案 0 :(得分:1)

首先,在JSON上使用正则表达式是邪恶的,几乎与杀死小猫一样糟糕。

如果您想将01表示为有效的JSON值,请考虑使用以下结构:

a = '{"index" : "01"}'
import json
json.loads(a)

如果您需要字符串文字01来充当数字,则可以考虑将其转换为Python脚本中的整数。

答案 1 :(得分:1)

https://grokbase.com/t/nutch/user/15a6hv8sg4/ocr-images-from-pdf-with-tika 请看上面的帖子 您需要使用自己的Decoder版本。

更多信息可以在这里的github中找到 How to convert string int JSON into real int with json.loads

c = '{"value": 02}'
value= json.loads(json.dumps(c))
print(value)

这似乎有效..很奇怪

> >>> c = '{"value": 02}'
> >>> import json
> >>> value= json.loads(json.dumps(c))
> >>> print(value) {"value": 02}
> >>> c = '{"value": 0002}'
> >>> value= json.loads(json.dumps(c))
> >>> print(value) {"value": 0002}

就像@Dunes一样,指出负载产生的字符串是结果,这不是有效的解决方案。 但是,

DEMJSON似乎正确解码了它。 https://github.com/simplejson/simplejson/blob/master/index.rst-另一种方式

>>> c = '{"value": 02}'
>>> import demjson
>>> demjson.decode(c)
{'value': 2}

答案 2 :(得分:1)

在JSON中,数字文字中的前导0无效,除非数字文字仅是字符0或以0.开头。 Python json模块非常严格,因为它不接受此类数字文字。部分原因是有时使用前导0表示八进制表示法,而不是十进制表示法。反序列化此类数字可能会导致意外的编程错误。也就是说,应将010解析为数字8(以八进制表示)还是解析为10(以十进制表示)。

您可以创建一个可以执行您想要的操作的解码器,但是您将需要大量修改json模块或重写其许多内部组件。无论哪种方式,您都将看到性能下降,因为您将不再使用该模块的C实现。

以下是一种可以解码JSON的实现,该JSON包含具有任意数量的前导零的数字。

import json
import re
import threading

# a more lenient number regex (modified from json.scanner.NUMBER_RE)
NUMBER_RE = re.compile(
    r'(-?(?:\d*))(\.\d+)?([eE][-+]?\d+)?',
    (re.VERBOSE | re.MULTILINE | re.DOTALL))


# we are going to be messing with the internals of `json.scanner`. As such we
# want to return it to its initial state when we're done with it, but we need to
# do so in a thread safe way.
_LOCK = threading.Lock()
def thread_safe_py_make_scanner(context, *, number_re=json.scanner.NUMBER_RE):
    with _LOCK:
        original_number_re = json.scanner.NUMBER_RE
        try:
            json.scanner.NUMBER_RE = number_re
            return json.scanner._original_py_make_scanner(context)
        finally:
            json.scanner.NUMBER_RE = original_number_re

json.scanner._original_py_make_scanner = json.scanner.py_make_scanner
json.scanner.py_make_scanner = thread_safe_py_make_scanner


class MyJsonDecoder(json.JSONDecoder):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # overwrite the stricter scan_once implementation
        self.scan_once = json.scanner.py_make_scanner(self, number_re=NUMBER_RE)


d = MyJsonDecoder()
n = d.decode('010')
assert n == 10

json.loads('010') # check the normal route still raise an error

我要强调的是,您不应依赖此作为适当的解决方案。相反,这是一个快速的技巧,可帮助您解码格式错误但几乎无效的JSON。如果由于某种原因而无法以有效形式重新创建JSON,这将非常有用。