2016-06-07 46 views
0

我讀一個JSON文件成Python其中包含轉義單引號(\」)。這會導致各種打嗝,正如討論過的那樣。 here。但是,我無法找到如何地址問題什麼。我只是做了一個有誤轉義字符買賣JSON

newstring=originalstring.replace(r"\'", "'") 

和東西解決。但這似乎相當難看。我無法在json docs中找到關於如何處理這種事情(創建異常或其他東西)的很多材料。

  • 對於這樣的問題,是否有一個很好的,乾淨的程序?

去回源是不可能的,很遺憾。

感謝您的幫助!

+1

的'\''字符序列的確是無效的JSON,因爲在JSON沒有這樣的轉義序列。你是如何產生這個輸出的? –

+0

嗨Martijn,我根本沒有生產它,只是處理給我的東西。顯然它是用「導出到PHPMyAdmin的JSON插件」創建的。 – patrick

+0

在這種情況下,是否考慮向該項目提交錯誤報告。 –

回答

1

JSON standard定義組特定的valid 2-character escape sequences\\\/\"\b\r\n\f\t,和一個4個字符的轉義序列來定義任何Unicode編碼點,\uhhhh\u加上4個十六進制位)。任何其他反斜槓序列加上其他字符是無效的JSON

如果你有一個JSON源無法修復,否則,唯一的出路就是刪除無效的序列,像你這樣做str.replace()哪怕是一點點脆弱的(它會打破時,有引號前的反斜槓序列)。

你可以使用正則表達式也一樣,在那裏你刪除一個有效的序列不使用任何反斜線

fixed = re.sub(r'(?<!\\)\\(?!["\\/bfnrt]|u[0-9a-fA-F]{4})', r'', inputstring) 

這不會趕上了一個奇怪的數反斜槓序列,例如\\\但會趕上其他任何東西:

>>> import re, json 
>>> broken = r'"JSON string with escaped quote: \' and various other broken escapes: \a \& \$ and a newline!\n"' 
>>> json.loads(broken) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.5/json/__init__.py", line 319, in loads 
    return _default_decoder.decode(s) 
    File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.5/json/decoder.py", line 339, in decode 
    obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 
    File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.5/json/decoder.py", line 355, in raw_decode 
    obj, end = self.scan_once(s, idx) 
json.decoder.JSONDecodeError: Invalid \escape: line 1 column 34 (char 33) 
>>> json.loads(re.sub(r'(?<!\\)\\(?!["\\/bfnrt]|u[0-9a-fA-F]{4})', r'', broken)) 
"JSON string with escaped quote: ' and various other broken escapes: a & $ and a newline!\n" 
+0

感謝您的幫助! – patrick

1

正確的做法是解決什麼是創建無效的JSON文件。但如果這是不可能的,我想替換是必要的。但是,你應該使用正則表達式,因此不會與\'取代\\' - 在這種情況下,第一反斜槓轉義第二個反斜槓,他們沒有逃避的報價。負面的逆序將會阻止這一點。

import re 
newstring = re.sub(r"(?<!\\)\\'", "'", originalstring) 
1

解決方案並不差。這看起來很醜,因爲這個問題很難看 - 你的數據已經損壞。這當然簡單,優雅,有效。如果子\\'(這三個大字,我不逃避任何東西)是存在的任何地方它只會失敗,而且當時只有連續斜線的數量是偶數。所以你的選擇是:

  1. 只是做你目前的事情,但首先檢查if r"\\'" in originalstring並拋出一個錯誤,如果是這樣。簡單,安全,可能很好。
  2. 對於(\\\\)+或其他東西,使用帶負向後置的正則表達式。
  3. 捕獲錯誤並使用錯誤的屬性來決定要替換的字符串的一部分。

看看這個片斷:

import json 
from json.decoder import JSONDecodeError 

s = r'"\'"' 
print(s) 
try: 
    print(json.loads(s)) 
except JSONDecodeError as e: 
    print(vars(e)) 

輸出:

"\'" 
{'msg': 'Invalid \\escape', 'colno': 2, 'doc': '"\\\'"', 'pos': 1, 'lineno': 1} 
+0

只有在Python 3中,異常才具有這些屬性;在Python 2中,所有你會得到的是一個'ValueError'異常,並且你不能解析這個信息的文本信息。 –

+0

順便說一句,你可以使用'json.JSONDecodeError',你不需要從'json.decoder'中導入它。 –

+0

是的,Python 2給了我一個'ValueError:Invalid \ escape': – patrick