2013-08-16 26 views
1

感謝您的期待!在JavaScript中解析格式錯誤的JSON

背景

我寫了一些消耗其返回畸形的JSON一個JSON服務前端代碼。具體而言,鍵不包圍引號:

{foo: "bar"} 

我沒有對服務的控制權,所以我糾正這種像這樣:

var scrubbedJson = dirtyJson.replace(/(['"])?([a-zA-Z0-9_]+)(['"])?:/g, '"$2": '); 

這給了我很好形成JSON:

{ 「foo」 的: 「酒吧」}

問題

然而,當我CA ll JSON.parse(scrubbedJson),我仍然收到錯誤。我懷疑這可能是因爲整個JSON字符串被雙引號包圍,但我不確定。

UPDATE

這已經解決了 - 上面的代碼工作正常。我在返回的JSON體內有一個流氓單引號。我從那裏得到了一切,現在一切都在解析。謝謝。 任何幫助,將不勝感激。

+0

您可以顯示服務實際返回的內容嗎?是的,如果整個字符串被雙引號包圍,它仍然是無效的JSON。 –

+1

另外,您是否可以修復該服務? –

+0

您可以假設會返回以下內容:'「{」foo「:」bar「}」'。我用'正則表達式'很糟糕。你知道這會如何治癒嗎? –

回答

2

這樣的事情可以幫助修復的JSON ..

$str='{foo:"bar"}'; 
echo preg_replace('/({)([a-zA-Z0-9]+)(:)/','$1"$2"${3}',$str); 

輸出:

{"foo":"bar"} 

編輯:

var str='{foo:"bar"}'; 
str.replace(/({)([a-zA-Z0-9]+)(:)/,'$1"$2"$3') 
+0

不知道爲什麼我把它放在php? var str ='{foo:「bar」}'; str.replace(/({)([a-zA-Z0-9] +)(:)/,'$ 1'$ 2「$ 3') –

+2

未能通過: str ='{foo:「bar」,foo2:「{foo:bar}」}' –

3

您可以完全避免靜態輸出使用正則表達式一個來自格式不正確的JSON字符串的JavaScript對象(不帶引號,單引號等的鍵),使用這個簡單的技巧:

var jsonify = (function(div){ 
    return function(json){ 
    div.setAttribute('onclick', 'this.__json__ = ' + json); 
    div.click(); 
    return div.__json__; 
    } 
})(document.createElement('div')); 

// Let's say you had a string like '{ one: 1 }' (malformed, a key without quotes) 
// jsonify('{ one: 1 }') will output a good ol' JS object ;) 

這裏有一個演示:http://codepen.io/csuwldcat/pen/dfzsu(打開控制檯)

-1

怎麼樣的項目?

function fixJson(json) { 
    var tempString, tempJson, output; 

    tempString = JSON.stringify(json); 
    tempJson = JSON.parse(tempString); 
    output = JSON.stringify(tempJson); 

    return output; 
} 
0

我試圖解決在Javascript中使用regEx的相同問題。我有一個爲Node.js編寫的應用程序來解析傳入的JSON,但需要解析器的「寬鬆」版本(請參閱下面的註釋),因爲引用每個關鍵字(名稱)都很不方便。這裏是我的解決方案:

var objKeysRegex = /({|,)(?:\s*)(?:')?([A-Za-z_$\.][A-Za-z0-9_ \-\.$]*)(?:')?(?:\s*):/g;// look for object names 
var newQuotedKeysString = originalString.replace(objKeysRegex, "$1\"$2\":");// all object names should be double quoted 
var newObject = JSON.parse(newQuotedKeysString); 

這裏的正則表達式的細分:

  • ({|,)查找對象的開始,扁平的物件嵌入式對象{,
  • (?:\s*)發現但不記得空格
  • (?:')?發現但不記得單引號(稍後將用雙引號替換)。將會有零或其中一個。
  • ([A-Za-z_$\.][A-Za-z0-9_ \-\.$]*)是名稱(或關鍵字)。以任何字母,下劃線,$或點開頭,後跟零個或多個字母數字字符或下劃線或破折號或圓點或$。
  • 最後一個字符:是從值中分隔對象的名稱。

現在我們可以使用replace()一些修整,讓我們的新報價鍵:

originalString.replace(objKeysRegex, "$1\"$2\":") 

其中$1或者是{,取決於對象是否被嵌入到另一個對象。 \"增加了一個雙引號。 $2是這個名字。 \"另一個雙引號。最後:完成它。 測試它與

{keyOne: "value1", $keyTwo: "value 2", key-3:{key4:18.34}} 

輸出:

{"keyOne": "value1","$keyTwo": "value 2","key-3":{"key4":18.34}} 

一些評論:

  • 我沒有測試速度這個方法,但是從我收集通過閱讀一些條目是使用正則表達式比eval()更快
  • 對於我的應用程序,我限制名稱ar e允許使用([A-Za-z_$\.][A-Za-z0-9_ \-\.$]*)作爲我的'寬鬆'版JSON解析器。如果你想允許更多的字符名稱(你可以這樣做,仍然有效),你可以改爲使用([^'":]+)來表示除雙引號或單引號或冒號以外的任何內容。這裏有各種各樣的東西,所以要小心。
  • 一個缺點是這種方法實際上改變了原來的傳入數據(但我認爲這就是你想要的?)。你可以編程來緩解這個問題 - 取決於你的需求和可用的資源。

希望這會有所幫助。 -John L.