2016-09-26 40 views
2

我有用戶提供JSON的CLI應用程序。我需要檢查JSON是否有效。 我發現服用點這樣可以極大的工作:檢查JSON LIKE字符串是否有效 - JS正則表達式

function isJsonValid(str) { 
    try { 
     JSON.parse(str); 
    } catch (e) { 
     return false; 
    } 
    return true; 
} 

但是當我調試我的應用我注意到,有從命令所有"'spaces被剝離了一點問題。 所以JSON爲:

{ 
    "key1": "value1", 
    "key2": "value2" 
} 

改變的東西如:

{key1:value1,key2:value2} 

我需要一個正則表達式將檢查該剝離JSON是有效的莫名其妙。

所以結果應該看起來像:

re.test({key1:value1,key2:value2}) // true 
re.test({key1:value1}) // true 
re.test({key1:value1,}) // false, extra comma 
re.test({key1:value1, key2}) // false, missing value of key2 
re.test({key1:value1, key2:value2) // false, missing closing } 
re.test({key1:value1, key2:value2}}) // false, extra closing } 

有人可以幫我與正則表達式的一部分?不幸的是,這不是我的強項。

+2

的「剝離」 JSON不再是JSON,但如果這是你輸入你想驗證它作爲是,你剛需要測試只顯示頂級「key:value」對的簡單情況,還是必須允許嵌套對象和/或數組? – nnnnnn

+0

是的,會有沒有嵌套的數組。所以我需要測試JSON是否如下所示:'{' - 開頭括號,'key' +':'+'value' +右括號'}''key:value'部分可以重複多次,並且應該分開用逗號 – Andurit

+0

???我在這裏錯過了重要的東西嗎?如果函數返回'true',則傳遞的JSON有效,如果返回'false',則發生錯誤,並且JSON無效。爲什麼要麻煩重新檢查? – Teemu

回答

3

正如我在上面的評論中提到的那樣,「剝離」的JSON當然不再是JSON。你已經確認你不需要擔心嵌套的對象或數組,只是大括號包圍的key:value對的簡單列表。

因此,下面的正則表達式假設每個鍵和值將被彌補的使用正則表達式\w等同於[A-Za-z0-9_]「字」字:

var re = /^\{\w+:\w+(,\w+:\w+)*\}$/; 

顯然,如果你想改變哪些字符允許作爲鍵名和值,您可以用替換每個\w,並根據需要添加或刪除允許的字符。

編輯:在你提到允許.在鍵名和值的評論。因此,使用不區分大小寫i標誌的正則表達式:

var re = /^\{[A-Z0-9._]+:[A-Z0-9._]+(,[A-Z0-9._]+:[A-Z0-9._]+)*\}$/i; 

但你可能要允許所有的作品之間的任意空白,所以我建議所有的標記之間添加\s*

var re = /^\s*\{\s*[A-Z0-9._]+\s*:\s*[A-Z0-9._]+\s*(,\s*[A-Z0-9._]+\s*:\s*[A-Z0-9._]+\s*)*\}\s*$/i; 
 

 
console.log(re.test('{key1:value1,key2:value2}')) // true 
 
console.log(re.test('{key1:value1}'))    // true 
 
console.log(re.test(' { key1 : value1 , key2 : value2 , k3 : v3 } ')) // true 
 
console.log(re.test(' { k.j.m : v.a2 , k2.a.b : v.32 , k3 : v3 } ')) // true 
 
console.log(re.test('{key1:value1,}'))    // false, extra comma 
 
console.log(re.test('{key1:value1, key2}'))   // false, missing value of key2 
 
console.log(re.test('{key1:value1, key2:value2')) // false, missing closing } 
 
console.log(re.test('{key1:value1, key2:value2}}')) // false, extra closing }

(請注意,我編輯的,允許在名稱.將允許多個在.字符位行,但我並不真的想繼續回來更新我的答案,因爲在原始文章中沒有提到更多的需求。如果你想在一行中嚴格保持一個.並且沒有前導或尾隨點,那麼就應用與上面用於使逗號工作的正則表達式相同的原理。)

+0

嗨@nnnnnn你能否考慮值或鍵不僅僅是簡單的字符串,而可以是'is.my.value'(所以之間加點) – Andurit

+0

是的,我在我的答案中已經提到:用方括號中允許的字符列表替換每個'\ w'。 – nnnnnn

2

在這裏,你有正則表達式:

^{(([a-zA-Z0-9]+:[a-zA-Z0-9]+)(,[a-zA-Z0-9]+:[a-zA-Z0-9]+)*)?}$ 

Check your Examples here at Regex101.com

+0

大拇指,謝謝你的好回答。我把nnnn標記爲正確的,因爲它比較複雜,他是第一個。不過,非常感謝你 – Andurit

+0

我很高興能幫上忙!有標記或不標記,我很高興你有最好的解決方案。 –

相關問題