如何在不使用Try/Catch的情况下检查字符串是否是JavaScript中的有效JSON字符串

Chi*_*han 495 javascript json

就像是:

var jsonString = '{ "Id": 1, "Name": "Coke" }';

//should be true
IsJsonString(jsonString);

//should be false
IsJsonString("foo");
IsJsonString("<div>foo</div>")
Run Code Online (Sandbox Code Playgroud)

解决方案不应包含try/catch.我们中的一些人打开"中断所有错误",他们不喜欢调试器打破那些无效的JSON字符串.

Gum*_*mbo 821

使用JSON解析器,如JSON.parse:

function IsJsonString(str) {
    try {
        JSON.parse(str);
    } catch (e) {
        return false;
    }
    return true;
}
Run Code Online (Sandbox Code Playgroud)

  • @Gumbo我的评论是1,5岁!:]我不记得了,两周前我在做什么,你让我想起那个项目?:] 没门... :] (26认同)
  • 这个答案的问题是,如果字符串确实检出,并且你解析它,你将解析它两次.难道你不能在错误的解析上返回false,但是在成功时返回对象吗? (8认同)
  • 谢谢,但我刚和团队一起运行,他们想要一些不使用try/catch的东西.编辑问题以及新标题.对于那个很抱歉. (7认同)
  • @Carcigenicate你可以做到这一点.但是,`JSON.parse("false")`也会计算为*false*. (5认同)
  • @trejder:这样做是因为1不是字符串,请用"1"来试试 (4认同)
  • 即使 str 是一个简单的“12345678”,这个答案也会返回 TRUE。您应该添加检查器的类型。 (2认同)
  • @user3651476那是因为“12345678”是一个有效的json字符串。JSON 文档有一个根节点,可以是 null、布尔值、数字、字符串、数组或对象。 (2认同)

Mat*_* H. 424

我知道这个问题已经迟了3年了,但我觉得自己好像在喋喋不休.

虽然Gumbo的解决方案效果很好,但它并没有处理几个没有引发异常的情况 JSON.parse({something that isn't JSON})

我也更喜欢同时返回解析的JSON,因此调用代码不必再次调用JSON.parse(jsonString).

这似乎适合我的需求:

function tryParseJSON (jsonString){
    try {
        var o = JSON.parse(jsonString);

        // Handle non-exception-throwing cases:
        // Neither JSON.parse(false) or JSON.parse(1234) throw errors, hence the type-checking,
        // but... JSON.parse(null) returns null, and typeof null === "object", 
        // so we must check for that, too. Thankfully, null is falsey, so this suffices:
        if (o && typeof o === "object") {
            return o;
        }
    }
    catch (e) { }

    return false;
};
Run Code Online (Sandbox Code Playgroud)

  • `o && o!== null`是多余的. (26认同)
  • 在页面上的答案中,这是最强大和最可靠的. (8认同)
  • 所以使用带有typeof的triple-equals,它总是返回一个字符串.:) (4认同)
  • 虽然是一个老帖子,我认为值得把[小提琴](https://jsfiddle.net/karlbateman/Lft2bzf1/)向上展示你的答案@matth,请注意对象无效..你必须传递一个JSON字符串.对于任何一个我猜的人来说,可能会派上用场. (4认同)
  • 该函数应返回`undefined`,而不是`false`,因为`false`是一个有效的json字符串,并且无法区分`tryParseJSON("false")`和`tryParseJSON("garbage")` (2认同)
  • 如何获得300多个投票?比@sparebytes说的最糟糕,此答案仅适用于字符串化的JSON对象!对于`tryParse(“ true”),`tryParse(“ 123”)等,它将返回false。这种方法没有意义。如果您只想检查有效的JSON字符串,请使用@Gumbo的解决方案。如果要使用解析结果,只需解析并使用它,如果抛出异常,请对其进行处理。 (2认同)

Mic*_*Mic 161

先评论一下.问题是关于不使用try/catch.
如果您不介意使用它,请阅读以下答案.这里我们只JSON使用正则表达式检查一个字符串,它在大多数情况下都有效,而不是所有情况.

浏览https://github.com/douglascrockford/JSON-js/blob/master/json2.js中的 450行

有一个regexp检查有效的JSON,如:

if (/^[\],:{}\s]*$/.test(text.replace(/\\["\\\/bfnrtu]/g, '@').
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {

  //the json is ok

}else{

  //the json is not ok

}
Run Code Online (Sandbox Code Playgroud)

编辑:新版本的json2.js进行了比上面更高级的解析,但仍然基于regexp替换(来自@Mrchief评论)

  • 这只是检查代码是否可以安全使用eval.例如,以下字符串'2011-6-27'将通过该测试. (53认同)
  • 您无法在JavaScript中测试字符串是否是带有正则表达式的有效JSON,因为JS正则表达式不支持允许您执行此操作的必要扩展(递归正则表达式).您的上述代码在"{"上失败. (8认同)
  • 仅仅因为它对他有所帮助,并不意味着它对我们其他人有所帮助,多年后他们也有同样的问题. (8认同)
  • @SystemicPlural,是的,但问题是关于不使用try/catch (4认同)
  • @Mic 我发表评论是因为你的答案说这是一种检查 JSON 是否有效的方法,但该正则表达式仅检查 eval() 是否安全。 (2认同)
  • @Mic json2.js不再使用该简单检查(而是使用4阶段解析来确定有效的JSON).建议修改或删除你的答案.请注意,我认为"没有将try/catch作为检查JSON的唯一机制"作为一种方法存在任何错误. (2认同)
  • JSON.parse`要快得多,大约0.2ms就能完成工作,而如果比较大约需要0.9ms的时间。 (2认同)

moe*_*ool 50

// vanillaJS
function isJSON(str) {
    try {
        return (JSON.parse(str) && !!str);
    } catch (e) {
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

用法: isJSON({})会的false,isJSON('{}')会的true.

要检查,如果事情是一个ArrayObject(解析 JSON):

// vanillaJS
function isAO(val) {
    return val instanceof Array || val instanceof Object ? true : false;
}

// ES2015
var isAO = (val) => val instanceof Array || val instanceof Object ? true : false;
Run Code Online (Sandbox Code Playgroud)

用法: isAO({})会的true,isAO('{}')会的false.

  • 小心,因为`null`通过了这个验证. (4认同)
  • `return !!(JSON.parse(str)&& str);`应该阻止空值.我将使用此代码更新答案. (2认同)

小智 22

这是我的工作代码:

function IsJsonString(str) {
  try {
    var json = JSON.parse(str);
    return (typeof json === 'object');
  } catch (e) {
    return false;
  }
}
Run Code Online (Sandbox Code Playgroud)

  • IsJsonString(null); //返回真。可以通过比较`typeof str === 'string'`来修复 (3认同)

kuk*_*kko 20

我用一个非常简单的方法检查一个字符串它是如何有效的JSON.

function testJSON(text){
    if (typeof text!=="string"){
        return false;
    }
    try{
        JSON.parse(text);
        return true;
    }
    catch (error){
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

具有有效JSON字符串的结果:

var input='["foo","bar",{"foo":"bar"}]';
testJSON(input); // returns true;
Run Code Online (Sandbox Code Playgroud)

结果是一个简单的字符串;

var input='This is not a JSON string.';
testJSON(input); // returns false;
Run Code Online (Sandbox Code Playgroud)

带有对象的结果:

var input={};
testJSON(input); // returns false;
Run Code Online (Sandbox Code Playgroud)

空输入的结果:

var input=null;
testJSON(input); // returns false;
Run Code Online (Sandbox Code Playgroud)

最后一个返回false,因为null变量的类型是object.

这适用于每次.:)


Ifi*_*Ifi 15

在原型js中我们有方法isJSON.试试看

http://api.prototypejs.org/language/string/prototype/isjson/

甚至http://www.prototypejs.org/learn/json

"something".isJSON();
// -> false
"\"something\"".isJSON();
// -> true
"{ foo: 42 }".isJSON();
// -> false
"{ \"foo\": 42 }".isJSON();
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,但我认为使用原型库来做这件事有点过分. (7认同)
  • 你给了四个例子但只有三个结果."{foo:42}"的结果是什么.isJSON()`?如果`false`,正如我所假设的那样(结果应该遵循它的文档),那么好的问题是,为什么它是假的?`{foo:42}`似乎是完全有效的JSON. (4认同)
  • @trejder不幸的是,JSON规范需要引用密钥. (4认同)
  • 并且"2002-12-15".isJSON返回true,而JSON.parse("2002-12-15")抛出错误. (4认同)
  • 我认为这里更好的答案是将该函数从原型库中拉出并放在这里.特别是因为http://api.prototypejs.org/language/string/prototype/isjson/是404. (4认同)

xam*_*mir 8

这里也是打字稿版本:

JSONTryParse(input: any) {
    try {
        //check if the string exists
        if (input) {
            var o = JSON.parse(input);

            //validate the result too
            if (o && o.constructor === Object) {
                return o;
            }
        }
    }
    catch (e: any) {
    }

    return false;
};
Run Code Online (Sandbox Code Playgroud)


Aka*_*ose 8

我参加聚会已经太晚了。这就是我最终所做的。使用快速正则表达式预检查可以大幅提高性能

if(/^\s*(\{|\[)/.test(str)){
    try{
        JSON.parse(str)
        // do something here, or return obj/true
    }catch(e){
        //  do nothing or return false
    }
}
Run Code Online (Sandbox Code Playgroud)

正则表达式将检查字符串是否以[或开头{。这将消除大多数错误案例(不是全部)。这是为您提供的快速性能测试https://jsbench.me/awl6fgn8jb/1

最坏的情况下,这可能比try直接使用慢 10-15%,最坏的情况意味着所有字符串都是有效的 json 字符串。

最好的情况是比 pure 快 99% try,最好的情况意味着所有字符串都是无效的 json。

这只查找解析为对象或数组的字符串。请注意,像“true”这样的字符串化 js-premitive 值是有效的 JSON 字符串,为了简单起见,我故意忽略它们。如需全面的预检查,请根据您的用例添加额外的检查。


小智 6

  • isValidJsonString - 检查有效的 json 字符串

  • JSON 数据类型 - 字符串、数字、对象(JSON 对象)、数组、布尔值、空值(https://www.json.org/json-en.html

  • javascript 中的假值 - false, 0, -0, 0n, ", null, undefined, NaN - ( https://developer.mozilla.org/en-US/docs/Glossary/Falsy )

  • JSON.parse

    • 适用于 number 、 boolean 、 null 并且有效的 json String 不会引发任何错误。请参考下面的例子

      • JSON.parse(2) // 2
      • JSON.parse(null) // 空
      • JSON.parse(true) // 真
      • JSON.parse('{"name":"jhamman"}') // {name: "jhamman"}
      • JSON.parse('[1,2,3]') // [1, 2, 3]
    • 解析 undefined 、对象、数组等时中断

      • 它给出了 Uncaught SyntaxError: Unexpected end of JSON input 。请参考下面的例子
      • JSON.parse({})
      • JSON.parse([])
      • JSON.parse(未定义)
      • JSON.parse("jack")
function isValidJsonString(jsonString){
    
    if(!(jsonString && typeof jsonString === "string")){
        return false;
    }

    try{
       JSON.parse(jsonString);
       return true;
    }catch(error){
        return false;
    }

}

Run Code Online (Sandbox Code Playgroud)


小智 5

也许它会有用:

    function parseJson(code)
{
    try {
        return JSON.parse(code);
    } catch (e) {
        return code;
    }
}
function parseJsonJQ(code)
{
    try {
        return $.parseJSON(code);
    } catch (e) {
        return code;
    }
}

var str =  "{\"a\":1,\"b\":2,\"c\":3,\"d\":4,\"e\":5}";
alert(typeof parseJson(str));
alert(typeof parseJsonJQ(str));
var str_b  = "c";
alert(typeof parseJson(str_b));
alert(typeof parseJsonJQ(str_b));
Run Code Online (Sandbox Code Playgroud)

输出:

IE7:字符串,对象,字符串,字符串

铬:对象,对象,字符串,字符串


Rab*_*bih 5

这个答案降低了 trycatch 语句的成本。

我使用 JQuery 来解析 JSON 字符串,并使用 trycatch 语句来处理异常,但是为不可解析的字符串抛出异常会减慢我的代码速度,所以我使用简单的 Regex 来检查字符串是否是可能的 JSON 字符串,而不会出现问题通过检查它的语法,然后我通过使用 JQuery 解析字符串来使用常规方法:

if (typeof jsonData == 'string') {
    if (! /^[\[|\{](\s|.*|\w)*[\]|\}]$/.test(jsonData)) {
        return jsonData;
    }
}

try {
    jsonData = $.parseJSON(jsonData);
} catch (e) {

}
Run Code Online (Sandbox Code Playgroud)

我将前面的代码包装在一个递归函数中来解析嵌套的 JSON 响应。


lor*_*isi 5

从原型框架String.isJSON定义这里

/**
   *  String#isJSON() -> Boolean
   *
   *  Check if the string is valid JSON by the use of regular expressions.
   *  This security method is called internally.
   *
   *  ##### Examples
   *
   *      "something".isJSON();
   *      // -> false
   *      "\"something\"".isJSON();
   *      // -> true
   *      "{ foo: 42 }".isJSON();
   *      // -> false
   *      "{ \"foo\": 42 }".isJSON();
   *      // -> true
  **/
  function isJSON() {
    var str = this;
    if (str.blank()) return false;
    str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@');
    str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
    str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
    return (/^[\],:{}\s]*$/).test(str);
  }
Run Code Online (Sandbox Code Playgroud)

所以这是可以用来传递字符串对象的版本

function isJSON(str) {
    if ( /^\s*$/.test(str) ) return false;
    str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@');
    str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
    str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
    return (/^[\],:{}\s]*$/).test(str);
  }
Run Code Online (Sandbox Code Playgroud)

/**
   *  String#isJSON() -> Boolean
   *
   *  Check if the string is valid JSON by the use of regular expressions.
   *  This security method is called internally.
   *
   *  ##### Examples
   *
   *      "something".isJSON();
   *      // -> false
   *      "\"something\"".isJSON();
   *      // -> true
   *      "{ foo: 42 }".isJSON();
   *      // -> false
   *      "{ \"foo\": 42 }".isJSON();
   *      // -> true
  **/
  function isJSON() {
    var str = this;
    if (str.blank()) return false;
    str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@');
    str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
    str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
    return (/^[\],:{}\s]*$/).test(str);
  }
Run Code Online (Sandbox Code Playgroud)


chr*_*xle 5

我想我知道你为什么要避免这种情况。但也许 try & catch !== try & catch。;o) 我想到了这一点:

var json_verify = function(s){ try { JSON.parse(s); return true; } catch (e) { return false; }};
Run Code Online (Sandbox Code Playgroud)

所以你也可以脏剪辑到 JSON 对象,比如:

JSON.verify = function(s){ try { JSON.parse(s); return true; } catch (e) { return false; }};
Run Code Online (Sandbox Code Playgroud)

由于这是尽可能封装的,它可能不会因错误而中断。


归档时间:

查看次数:

514414 次

最近记录:

6 年 前