簡體   English   中英

將帶前導零整數的字符串轉換為json

[英]Converting string with leading-zero integer to json

我使用json -library將字符串轉換為json-object:

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

但是,如果我改為將字符串a更改為包含前導0,那么它會分解:

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

我相信這是因為如果一個整數以此線程中描述的前導零開頭,則它是無效的JSON。

有辦法解決這個問題嗎? 如果沒有,那么我想最好的方法是首先從字符串中刪除正則表達式的任何前導零,然后轉換為json?

首先,在JSON上使用正則表達式是邪惡的,幾乎和殺死小貓一樣糟糕。

如果要將01表示為有效的JSON值,請考慮使用此結構:

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

如果您需要字符串文字01的行為類似於數字,那么請考慮將其轉換為Python腳本中的整數。

如何使用json.loads將string int JSON轉換為real int請參閱上面的帖子您需要使用自己的Decoder版本。

更多信息可以在這里找到,在github https://github.com/simplejson/simplejson/blob/master/index.rst

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所指出的那樣,load會產生字符串作為結果,這不是一個有效的解決方案。 然而,

DEMJSON似乎正確解碼它。 https://pypi.org/project/demjson/ - 替代方式

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

除非數字文字只是字符0或以0.開頭,否則JSON中數字文字中的前導0無效。 Python json模塊非常嚴格,因為它不接受這樣的數字文字。 部分原因是前導0有時用於表示八進制表示法而不是十進制表示法。 對這些數字進行反序列化可能會導致意外的編程錯誤。 也就是說,應將010解析為數字8 (八進制表示法)或10 (十進制表示法)。

您可以創建一個可以執行您想要的解碼器,但是您需要嚴重破解json模塊或重寫其內部的大部分內容。 無論哪種方式,您將看到性能變慢,因為您將不再使用模塊的C實現。

下面是一個可以解碼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,則此選項很有用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM