我有CLI应用程序,用户提供JSON。我需要检查JSON是否有效。 我发现这样的事情可能很有用:
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 }
有人可以帮我解决正则表达式部分吗?不幸的是,这不是我强有力的一面。
答案 0 :(得分:3)
正如我在上面的评论中所提到的,“剥离的”JSON当然不再是JSON。您已经确认不需要担心嵌套对象或数组,只需要用大括号括起来的key:value
对的简单列表。
因此,以下正则表达式假设每个键和值将使用等同于\w
的正则表达式[A-Za-z0-9_]
由“单词”字符组成:
var re = /^\{\w+:\w+(,\w+:\w+)*\}$/;
显然,如果您想要更改允许哪些字符作为键名和值,您可以将\w
替换为[A-Za-z0-9_]
,只需根据需要添加或删除允许的字符。
编辑:在评论中,您提到在密钥名称和值中允许.
。所以在正则表达式上使用不区分大小写的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 }
(请注意,我在名称中编辑以允许.
的位将允许连续多个.
个字符,但我真的不想继续更新我的答案因为原始帖子中没有提到更多的要求。如果你想严格保持一行.
并且没有前导或尾随点,那么只应用与上述正则表达式相同的原则逗号工作。)
答案 1 :(得分:2)
这里有正则表达式:
^{(([a-zA-Z0-9]+:[a-zA-Z0-9]+)(,[a-zA-Z0-9]+:[a-zA-Z0-9]+)*)?}$