如何在Javascript中提取不完整JSON数组中的对象值?

如何在Javascript中提取不完整JSON数组中的对象值?,javascript,arrays,json,node.js,Javascript,Arrays,Json,Node.js,我有一个节点应用程序,可以从中获取一些数据。我已经问过其他的问题了,但是我想不出来。我需要访问结果的值。下面的代码显示了我从服务器得到的确切响应。其他答案中描述的方法,如JSON.parse()等,似乎都不起作用 [{ query: { "parameter1": "12", "parameter2": "13", "parameter3": 25 }

我有一个节点应用程序,可以从中获取一些数据。我已经问过其他的问题了,但是我想不出来。我需要访问结果的值。下面的代码显示了我从服务器得到的确切响应。其他答案中描述的方法,如JSON.parse()等,似乎都不起作用

    [{
      query: {
                "parameter1": "12",
                "parameter2": "13",
                "parameter3": 25
               }
      result: 6.58443
    }]
编辑:正如下面的评论中提到的,不幸的是我无法在服务器端解决这个问题(来自外部源)。我必须在我这方面处理这个损坏的JSON,并提取结果的值。
编辑2:是的,有多个这样的数组。内容和逗号部分不变。它们一个接一个地列出。

您可以做的是用反勾号封装结果以获得(有效)字符串文字,然后使用您想要的任何方法获取结果,例如匹配的正则表达式:

var-arr=`[{
“查询”:{
“参数1”:“12”,
“参数2”:“13”,
“参数3”:25
}
“结果”:6.58443
}]`;
var match=arr.match(/(“结果”)(\d*\d*)/;

console.log(匹配[2])您可以做的是用反勾号封装结果以获得(有效)字符串文字,然后使用您想要的任何方法获取结果,例如匹配的正则表达式:

var-arr=`[{
“查询”:{
“参数1”:“12”,
“参数2”:“13”,
“参数3”:25
}
“结果”:6.58443
}]`;
var match=arr.match(/(“结果”)(\d*\d*)/;

console.log(匹配[2])
尽管您无法通过任何需要JSON的库函数接收数据,比如jQuery$.ajax(),带有
dataType='JSON'
选项(在这种情况下,您应该使用
dataType=“text”
,以避免过早触发错误)

…显然,在解析JSON之前,您需要先修复JSON语法(据我所知,您已经知道)

如果这是您想要的,那么最好的选择是正则表达式搜索和替换

如果你知道你不会得到像“{括号:“}”}”这样的东西,那很简单:

示例:

var wrong = `
    [{
      "query": {
                "parameter1": "12",
                "parameter2": "13",
                "parameter3": 25
               }
      "result": 6.58443
    }]
`;

var good = wrong.replace(/}(?!\s*[,}\]])/g, '},');

var json = JSON.parse(good);

console.log(json);
这是修复您提供的输入的最简单示例

即使它在数组结束(']')之后并没有修复相同的问题,而且最重要的是,如果它被修复了(或者仅仅是字符串以'}'而不是']'结尾),它会在最后添加一个额外的'',再次把事情搞砸

解决上述问题的一种更礼貌的方法是将前面代码中的
var good=…
行替换为以下行:

var good = wrong.replace(/(}|])(?!\s*[,}\]])/g, '$1,')
    .replace(/,\s*$/, '')
;
现在,您有了一个有效的json对象,因此访问其中的任何属性都是显而易见的。例如,
json[0]。结果就是您所要求的


另一方面,如果您可以在文本字符串中使用括号,这将非常困难(甚至不是不可能)。但我发现情况很难如此…

,尽管您无法通过任何需要JSON的库函数(如jQuery$.ajax()和
dataType='JSON'
选项)接收数据(在这种情况下,您应该使用
dataType=“text”
,以避免触发过早的错误

…显然,在解析JSON之前,您需要先修复JSON语法(据我所知,您已经知道)

如果这是您想要的,那么最好的选择是正则表达式搜索和替换

如果你知道你不会得到像“{括号:“}”}”这样的东西,那很简单:

示例:

var wrong = `
    [{
      "query": {
                "parameter1": "12",
                "parameter2": "13",
                "parameter3": 25
               }
      "result": 6.58443
    }]
`;

var good = wrong.replace(/}(?!\s*[,}\]])/g, '},');

var json = JSON.parse(good);

console.log(json);
这是修复您提供的输入的最简单示例

即使它在数组结束(']')之后并没有修复相同的问题,而且最重要的是,如果它被修复了(或者仅仅是字符串以'}'而不是']'结尾),它会在最后添加一个额外的'',再次把事情搞砸

解决上述问题的一种更礼貌的方法是将前面代码中的
var good=…
行替换为以下行:

var good = wrong.replace(/(}|])(?!\s*[,}\]])/g, '$1,')
    .replace(/,\s*$/, '')
;
现在,您有了一个有效的json对象,因此访问其中的任何属性都是显而易见的。例如,
json[0]。结果就是您所要求的


另一方面,如果可以在文本字符串中使用括号,那么这将非常困难(甚至不是不可能).但我发现这很难…

以上提供的建议都指向了一种解决此问题的黑客方法。解决此问题的唯一方法是使用好的旧正则表达式。令我惊讶的是..尽管有很多库可以处理JSON解析等,但可以解决边缘情况(在处理小客户机或不可靠的数据源时很常见),没有库可以处理这种情况。
@Bitifet的答案是解决这个问题的方法。使用正则表达式。

上面提供的建议都指向了一种解决这个问题的黑客方法。解决这个问题的唯一方法是使用好的旧正则表达式。令我惊讶的是。。尽管有很多库可以处理JSON解析等,但可以解决边缘情况(在处理小客户机或不可靠的数据源时很常见),没有库可以处理这种情况。
@Bitifet的答案就是解决这个问题的方法。对于regex.

纯粹出于说明目的,下面的代码“重写”将缺少逗号的JSON转换为在适当位置有逗号的JSON。与
replace
或正则表达式相比,使用此代码的优势在于可以确保正确处理字符串文本:

const LEX_EXPR = (
  '('
    + '"(?:\\\\(?:["\\\\/bfnrt]|u[a-fA-F0-9]{4})|[^"])*"|'
    + '-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?|'
    + '(?:true|false|null)'
  + ')|'
  + '([{\\[])|'
  + '([}\\]])|'
  + '([:,])|'
  + '(\\s+)|'
  + '(.)'
)

function lex(string) {
  let tokens = []
  let expr = new RegExp(LEX_EXPR, 'mguy')
  let match = expr.exec(string)
  while(match !== null) {
    let [
      value,
      atom,
      begin, end, sep,
      whitespace,
      junk
    ] = match
    let type
    if (atom != null) {
      type = "atom"
    } else if (begin != null) {
      type = "begin"
    } else if (end != null) {
      type = "end"
    } else if (sep != null) {
      type = "sep"
    } else if (whitespace != null) {
      type = "whitespace"
    } else {
      // junk. ignore or raise exception
      throw `Invalid character: ${junk}`
    }
    tokens.push({ type, value })
    match = expr.exec(string)
  }
  return tokens
}

function shouldInsertComma(prev, cur) {
  if (!prev || !cur) {
    return false
  }
  if (prev.type == "begin" || prev.type == "sep") {
    return false
  }
  return cur.type == "begin" || cur.type == "atom"
}

function rewrite(tokens) {
  let out = []
  let prevNonWhitespace = null
  for (let i = 0; i < tokens.length; i++) {
    let cur = tokens[i]
    if (cur.type !== "whitespace") {
      if (shouldInsertComma(prevNonWhitespace, cur)) {
        out.push({ type: "sep", value: "," })
      }
      prevNonWhitespace = cur
    }
    out.push(cur)
  }
  return out
}

function joinTokens(tokens) {
  return tokens.map(({ value }) => value).join('')
}

const invalid = `
{
  "foo": {
    "bat": "bing}"
    "boo": "bug"
  }
  "result": "yes"
}
`
const rewritten = joinTokens(rewrite(lex(invalid)))
console.log(JSON.parse(rewritten))  // { foo: { bat: 'bing}', boo: 'bug' }, result: 'yes' }
const LEX_EXPR=(
'('
+“(?:\\\\(?:[”\\\\\/bfnrt]| u[a-fA-F0-9]{4})|[^])*”|”
+“-?\\d+(?:\.\\d+)(?:[eE][+-]?\\d+)”
+“(?:真|假|空)”
+ ')|'
+ '([{\\[])|'
+ '([}\\]])|'
+ '([:,])|'
+“(\\s+)|”
+ '(.)'
)
函数lex(字符串){
让令牌=[]
设expr=newregexp(LEX_expr,'mguy')
让match=expr.exec(字符串)
while(匹配!==null){
让[
价值
原子,