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