我有一个节点应用程序,我可以从中获取一些数据。我已经经历了其他问题,但是我无法弄清楚这一点。我需要访问 result 的值。下面的代码显示了我从服务器获得的确切响应。其他答案中描述的方法(如JSON.parse()等)似乎都不起作用。
[{
query: {
"parameter1": "12",
"parameter2": "13",
"parameter3": 25
}
result: 6.58443
}]
编辑:正如下面的评论所述,遗憾的是我无法在服务器端修复此问题(来自外部源)。我必须在我的结尾处理这个破碎的JSON并提取结果的值。
编辑2:是的,有这样的多个阵列。内容和逗号部分没有变化。它们是一个接一个列出的。
答案 0 :(得分:2)
尽管您无法通过任何需要JSON的库函数(例如带有dataType='json'
选项的jQuery $ .ajax()来接收该数据(在这种情况下您应该使用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
就是你要求的。
另一方面,如果你可以在文字字符串中包含括号,那将会更加困难(甚至不是不可能)。但我发现情况很难......
答案 1 :(得分:0)
你可以做的是用反向标记封装你的结果以获得(有效的)字符串文字,然后用你想要的任何方法获得结果,例如匹配的正则表达式:
var arr = `[{
"query": {
"parameter1": "12",
"parameter2": "13",
"parameter3": 25
}
"result": 6.58443
}]`;
var match = arr.match(/("result": )(\d*.\d*)/);
console.log(match[2]);

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