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

问题描述 投票:0回答:4

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

    [{
      query: {
                "parameter1": "12",
                "parameter2": "13",
                "parameter3": 25
               }
      result: 6.58443
    }]

编辑:正如下面的评论中提到的,不幸的是我无法解决这个问题在服务器端(来自外部源)。我必须在我的结尾处理这个破碎的JSON并提取结果的值。编辑2:是的,有这样的多个阵列。内容和逗号部分没有变化。它们一个接一个地列出。

javascript arrays json node.js
4个回答
2
投票

尽管事实上你不能通过任何库函数来接收那些数据,这些库函数需要JSON,例如jQuery $ .ajax()和dataType='json'选项(在这种情况下你应该使用dataType="text"以避免触发过早的错误我的意思)。

...你明显需要在解析它之前修复JSON语法(据我所知你已经知道)。

如果这是你要求的,你最好的选择是正则表达式搜索和替换。

如果你知道你不会得到诸如'{bracket:“}}}'之类的东西,那很简单:

例:

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].result就是你要求的。

另一方面,如果你可以在文字字符串中包含括号,那将会更加困难(甚至不是不可能)。但我发现情况很难......


0
投票

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

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

var match = arr.match(/("result": )(\d*.\d*)/);

console.log(match[2]);

0
投票

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


0
投票

纯粹为了说明的目的,下面的代码“重写”了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' }
© www.soinside.com 2019 - 2024. All rights reserved.