2016-08-29 116 views
0

試圖在Python錯誤解析JSON在Python

'''[{"accountName":"London\"Paris\"Geneva","accountId":"1664800781","isActive":true,"timeZone":"Asia/Jerusalem","currency":"ILS"}]''' 

解析此JSON給出了這樣的錯誤

Traceback (most recent call last): 
    File "unicode_test.py", line 5, in <module> 
    parsed_json = json.loads(json3) 
    File "/usr/lib/python2.7/json/__init__.py", line 338, in loads 
    return _default_decoder.decode(s) 
    File "/usr/lib/python2.7/json/decoder.py", line 366, in decode 
    obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 
    File "/usr/lib/python2.7/json/decoder.py", line 382, in raw_decode 
    obj, end = self.scan_once(s, idx) 
ValueError: Expecting , delimiter: line 1 column 25 (char 24) 

,而此JSON解析罰款(增加額外的 '\')

'''[{"accountName":"London\\"Paris\\"Geneva","accountId":"1664800781","isActive":true,"timeZone":"Asia/Jerusalem","currency":"ILS"}]''' 

使用此代碼:

import json 

json3 = '''[{"accountName":"London\\"Paris\\"Geneva","accountId":"1664800781","isActive":true,"timeZone":"Asia/Jerusalem","currency":"ILS"}]''' 

parsed_json = json.loads(json3) 
print json.dumps(parsed_json) 
print parsed_json[0]['accountName'] 

但產量一直我迷惑, json.dumps()輸出

[{"currency": "ILS", "timeZone": "Asia/Jerusalem", "accountId": "1664800781", "isActive": true, "accountName": "London\"Paris\"Geneva"}] 

實際帳戶名字符串

London"Paris"Geneva 

我怎樣才能獲得JSON字符串London"Paris"Geneva

+0

你是如何獲取數據?你是在交互式提示下輸入它,還是從文件中讀取它? –

+0

您是否嘗試將您的字符串標記爲原始? ('r'''bla'''''而不是''''bla'''') – janbrohl

+0

@BryanOakley我會從GET調用中獲取數據,但爲了說明它只是文件中的一個字符串 – abhik

回答

0

您面臨的問題叫做character escaping。解析器確實按預期工作;這是大多數編程語言的共同話題。

在你的具體的例子,你想一個值,這本身就是雙引號中內使用雙引號",像這樣:

'accountName': "London'Paris'Geneva", 

爲了解析您預期的字符串,我會做一些像這樣:

import json 

json3 = '''[{"accountName": "London\'Paris\'Geneva", "accountId": "1664800781", "isActive": "true", "timeZone": "Asia/Jerusalem", "currency": "ILS"}]''' 

parsed_json = json.loads(json3) 
print (json.dumps(parsed_json)) 
print (parsed_json[0]['accountName']) 

產生以下輸出:

[{"currency": "ILS", "timeZone": "Asia/Jerusalem", "accountId": "1664800781", "isActive": "true", "accountName": "London'Paris'Geneva"}] 
London'Paris'Geneva 
+0

爲什麼在第一個示例中使用單個反斜槓拋出錯誤轉義雙引號?而用雙反斜槓轉義給我''倫敦\「巴黎\」日內瓦'',而我想''倫敦\「巴黎\」日內瓦\「' – abhik

+0

因爲您使用雙引號(」)來分離值,我會編輯我的答案以反映這一點。 – Av4t4r

0

在字符串文字中帶有\的前面引號稱爲轉義它,並告訴解析器,您實際上意味着該字符串包含引號,而不是在該處結束字符串。 Python有兩個其他選項:使用不同類型的引號來包裝字符串,或者在字符串之前放置r,這意味着大致「假設所有引號和反斜線已經被轉義。」

這裏發生的是,json模塊再逃避的東西輸出的一致性 - 如果您加載一些json,放棄它,然後加載你傾倒的東西,它不應該改變。然後json將讀取該字符串,所以您需要雙反斜槓,以便引號再次轉義。如果json加載包含雙引號的字符串文字,那麼字符串文字將需要在引號前面加上\\\,用單引號括起來,並且引號前面加上\\,否則就是原始字符串。

簡化你的榜樣,三件事情會工作:

test = "{\"accountName\": \"London\\\"Paris\\\"Geneva\"}" 

(逃避所有內部引號,也難逃反斜槓圍繞「巴黎」,供以後再次逃脫)

test = '{"accountName": "London\\"Paris\\"Geneva"}' 

(使用單引號意味着你不需要逃脫雙引號,但你仍然需要逃離反斜槓,因爲你可以周逃逸的事情,即使你不需要來,和你實際上並不想在這種情況下)。

test = r'{"accountName": "London\"Paris\"Geneva"}' 

(使用原始字符串意味着你告訴它沒有任何東西可以逃脫,所以你可以安全地使用反斜槓,但你仍然需要用單引號來包裹它,以便雙引號不會結束它)

所有這三個實際上代表一個字符串,其中包含"鍵和值,用\之前的"中的中間值:'{"accountName": "London\"Paris\"Geneva"}'但一般會被打印爲\\代替\讓你知道它的字面\而不是在下面的字符轉義。這就是說:

>>> print test 
'{"accountName": "London\\"Paris\\"Geneva"}' 
>>> print test[23] 
'\\' 

\\在屏幕上,它利用空間兩個字符的表示,但在內部表示單個字符\

json.loads(test)輸出,然後,是一個dict

{'accountName': 'London"Paris"Geneva'} 

而且json.dumps(json.loads(test)) == test

如果你想json再次轉儲,它需要重新逃生者的報價讓事情變得可讀 - 如果它沒有放回反斜槓,嘗試重新加載會導致出現錯誤,因爲它太早觸及未經引用的報價。您將無法使json轉儲包含未轉義引號的字符串在字符串中間,因爲它需要始終轉儲可讀的JSON文本,這些文本可以加載以產生與轉儲相同的結構。如果你必須有實際的字符串包含雙引號,你的選擇要麼是:

  1. json放棄吧,再對其進行處理後,除去反斜槓。如果輸出字符串仍然是test,那麼您將運行test.replace(r'\"', r'"')
  2. 以某種方式處理您的對象,而不是通過json.dumps(),在這種情況下,您可以或多或少地進行處理,無論您喜歡。

無論哪種方式,但是,你將無法讀取JSON作爲結果同樣沒有在添加這些回。