2016-09-26 85 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

我很高兴能帮上忙!有标记或不标记,我很高兴你有最好的解决方案。 –

相关问题