admin管理员组文章数量:1025301
I want to extract all JSON objects from a string randomly containing them and add them to an array.
Sample string:
"I was with {"name":"John"}{"name":"Anne"}{"name":"Daniel"} yesterday"`
how can i extract the JSON objects from this sample string?
I want to extract all JSON objects from a string randomly containing them and add them to an array.
Sample string:
"I was with {"name":"John"}{"name":"Anne"}{"name":"Daniel"} yesterday"`
how can i extract the JSON objects from this sample string?
Share Improve this question edited Apr 16, 2015 at 13:16 TeraTon 4356 silver badges15 bronze badges asked Apr 16, 2015 at 12:17 FadiYFadiY 1191 gold badge2 silver badges10 bronze badges 5- Post your sample JSON string – Vigneswaran Marimuthu Commented Apr 16, 2015 at 12:18
- Show the code what you have tried so far... And some example string. – user1846747 Commented Apr 16, 2015 at 12:19
- you can use JSON.parse(jsonString); where jsonString is a valid jsonstring – Robin Commented Apr 16, 2015 at 12:20
- So you want to parse a string with semirandom content for any JSON objects in it? – TeraTon Commented Apr 16, 2015 at 12:36
- Yes exactly! Then add those objects to an array. – FadiY Commented Apr 16, 2015 at 12:38
4 Answers
Reset to default 4This is what worked for me:
const regex = /[{\[]{1}([,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]|".*?")+[}\]]{1}/gis;
function jsonFromString(str) {
const matches = str.match(regex);
return Object.assign({}, ...matches.map((m) => JSON.parse(m)));
}
console.log(jsonFromString(`Hi, my {"name": "Kingerious"} and my {"age": 14}`));
Explanation
- Regex is first used to identify all valid JSON objects using
str.match()
function. It returns an array with all the objects. - Then the array is looped over, parsed into JS objects and then merged to create one single object.
Source
Regex: https://stackoverflow./a/45167612/17152934
One approach to this is to use the str.search(regexp) function to find all parts of it that fulfill the JSON regex found here. So you could write a function that searches over the string for regexp matches.
To actually extract the object from the string you could use these two functions for the regex and then loop over the string until all objects have been found.
var match = str.match(regex);
var firstIndex = str.indexOf(match[0]);
var lastIndex = str.lastIndexOf(match[match.length-1]);
var JSONobjects = [];
while( str.match(regex){
//extract the wanted part.
jsonObject = substr(str.indexOf(match[0],str.lastIndexOf(match[match.length1-]));
//remove the already found json part from the string and continue
str.splice(str.indexOf(match[0],str.indexOf(match[0] + jsonObject.length());
//parse the JSON object and add it to an array.
JSONobjects.push(JSON.parse(jsonObject));
}
I modified the one that Kingerious made to make it recognize strings as well and to return an array of the objects instead of a single object with all of the other objects as its properties:
const regex = /([{\[]{1}([,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]|".*?")+[}\]]{1}|["]{1}(([^(")]|\\")*)+(?<!\\)["]){1}/gis;
function jsonFromString(str) {
const matches = str.match(regex);
return matches.map((m) => JSON.parse(m));
}
console.log(jsonFromString(`some text {"val}ue": "something:some{thing"} and "teststri\\"n{g" some more other text [{"testa": 5, "testb": "t\\"\\"est6"}, {"testc": "1", "testd": "test45678"}, "teste", {"testf": {"testg": true, "testh": false}}] other extra added text {"somenumber": 14} "somestring"`)); //it can detect the json correctly even if you have other brackets or escaped quotation marks (\") inside of the strings.
Here is an even better version of this that uses a custom JSONParse() function to parse the JSON while also keeping Infinity, -Infinity, Undefined, NaN, and Null values:
function JSONParse(JSONString, keepUndefined = true){
let g = [];
let h = [];
let a = JSON.parse(JSONString.replace(/(?<="(?:\s*):(?:\s*))"{{(Infinity|NaN|-Infinity|undefined)}}"(?=(?:\s*)[,}](?:\s*))/g, '"{{\\"{{$1}}\\"}}"').replace(/(?<="(?:\s*):(?:\s*))(Infinity|NaN|-Infinity|undefined)(?=(?:\s*)[,}](?:\s*))/g, '"{{$1}}"'), function(k, v) {
if (v === '{{Infinity}}') return Infinity;
else if (v === '{{-Infinity}}') return -Infinity;
else if (v === '{{NaN}}') return NaN;
else if (v === '{{undefined}}') {g.push(k); if(keepUndefined){return v}else{undefined}};
h.push(k);
return v;
});
g.forEach((v, i)=>{
let b = Object.entries(a);
b[b.findIndex(b=>b[0]==v)]=[v, undefined];
a=Object.fromEntries(b)
});
{
let b = Object.entries(a);
!!b.filter(b=>String(b[1]).match(/^{{"{{(Infinity|NaN|-Infinity|undefined)}}"}}$/)).forEach((v, i)=>{
b[b.findIndex(b=>b[0]==v[0])]=[v[0], v[1].replace(/^(?:{{"{{)(Infinity|NaN|-Infinity|undefined)(?:}}"}})$/g, '{{$1}}')];
a=Object.fromEntries(b)
})
};
return a;
}
function JSONStringify(JSONObject, keepUndefined = false){
return JSON.stringify(JSONObject, function(k, v) {
if (v === Infinity) return "{{Infinity}}";
else if (v === -Infinity) return "{{-Infinity}}";
else if (Number.isNaN(v)) return "{{NaN}}";
else if (v === undefined && keepUndefined) return "{{undefined}}";
if(String(v).match(/^{{(Infinity|NaN|-Infinity|undefined)}}$/)){
v=v.replace(/^{{(Infinity|NaN|-Infinity|undefined)}}$/g, '{{"{{$1}}"}}')
}
return v;
}).replace(/(?<!\\)"{{(Infinity|NaN|-Infinity|undefined)}}"/g, '$1').replace(/(?<!\\)"{{\\"{{(Infinity|NaN|-Infinity|undefined)}}\\"}}"/g, '"{{$1}}"');
}
const jsonFromStringRegex = /([{\[]{1}([,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]|".*?")+[}\]]{1}|["]{1}(([^(")]|\\")*)+(?<!\\)["]){1}/gis;
function jsonFromString(str) {
const matches = str.match(jsonFromStringRegex);
return matches.map((m) => JSONParse(m, true));
}
function jsonStringsFromString(str) {
const matches = str.match(jsonFromStringRegex);
return matches.map((m) => m);
}//returns the substrings that were detected as json without parsing them
//example parsing all the JSON from the text
console.log(jsonFromString(`some text {"val}ue": "something:some{thing"} and "teststri\\"n{g" some more other text [{"testa": 5, "testb": "t\\"\\"est6"}, {"testc": "1", "testd": "test45678"}, "teste", {"testf": {"testg": true, "testh": false}}] other extra added text {"somenumber": 14, "someothernumber": Infinity, "another number": -Infinity, "somenullvalue": null, "someundefinedvalue": undefined, "someNaNvalue": NaN} "somestring"`)); //it can detect the json correctly even if you have other brackets or escaped quotation marks (\") inside of the strings.
//example stringifying all the JSON parsed from the text
console.log(JSONStringify(jsonFromString(`some text {"val}ue": "something:some{thing"} and "teststri\\"n{g" some more other text [{"testa": 5, "testb": "t\\"\\"est6"}, {"testc": "1", "testd": "test45678"}, "teste", {"testf": {"testg": true, "testh": false}}] other extra added text {"somenumber": 14, "someothernumber": Infinity, "another number": -Infinity, "somenullvalue": null, "someundefinedvalue": undefined, "someNaNvalue": NaN} "somestring"`)));
var a = JSON.parse('{"name":"John"}');
a ==> Object {name: "John"}
var b = [];
b.push(a);
I want to extract all JSON objects from a string randomly containing them and add them to an array.
Sample string:
"I was with {"name":"John"}{"name":"Anne"}{"name":"Daniel"} yesterday"`
how can i extract the JSON objects from this sample string?
I want to extract all JSON objects from a string randomly containing them and add them to an array.
Sample string:
"I was with {"name":"John"}{"name":"Anne"}{"name":"Daniel"} yesterday"`
how can i extract the JSON objects from this sample string?
Share Improve this question edited Apr 16, 2015 at 13:16 TeraTon 4356 silver badges15 bronze badges asked Apr 16, 2015 at 12:17 FadiYFadiY 1191 gold badge2 silver badges10 bronze badges 5- Post your sample JSON string – Vigneswaran Marimuthu Commented Apr 16, 2015 at 12:18
- Show the code what you have tried so far... And some example string. – user1846747 Commented Apr 16, 2015 at 12:19
- you can use JSON.parse(jsonString); where jsonString is a valid jsonstring – Robin Commented Apr 16, 2015 at 12:20
- So you want to parse a string with semirandom content for any JSON objects in it? – TeraTon Commented Apr 16, 2015 at 12:36
- Yes exactly! Then add those objects to an array. – FadiY Commented Apr 16, 2015 at 12:38
4 Answers
Reset to default 4This is what worked for me:
const regex = /[{\[]{1}([,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]|".*?")+[}\]]{1}/gis;
function jsonFromString(str) {
const matches = str.match(regex);
return Object.assign({}, ...matches.map((m) => JSON.parse(m)));
}
console.log(jsonFromString(`Hi, my {"name": "Kingerious"} and my {"age": 14}`));
Explanation
- Regex is first used to identify all valid JSON objects using
str.match()
function. It returns an array with all the objects. - Then the array is looped over, parsed into JS objects and then merged to create one single object.
Source
Regex: https://stackoverflow./a/45167612/17152934
One approach to this is to use the str.search(regexp) function to find all parts of it that fulfill the JSON regex found here. So you could write a function that searches over the string for regexp matches.
To actually extract the object from the string you could use these two functions for the regex and then loop over the string until all objects have been found.
var match = str.match(regex);
var firstIndex = str.indexOf(match[0]);
var lastIndex = str.lastIndexOf(match[match.length-1]);
var JSONobjects = [];
while( str.match(regex){
//extract the wanted part.
jsonObject = substr(str.indexOf(match[0],str.lastIndexOf(match[match.length1-]));
//remove the already found json part from the string and continue
str.splice(str.indexOf(match[0],str.indexOf(match[0] + jsonObject.length());
//parse the JSON object and add it to an array.
JSONobjects.push(JSON.parse(jsonObject));
}
I modified the one that Kingerious made to make it recognize strings as well and to return an array of the objects instead of a single object with all of the other objects as its properties:
const regex = /([{\[]{1}([,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]|".*?")+[}\]]{1}|["]{1}(([^(")]|\\")*)+(?<!\\)["]){1}/gis;
function jsonFromString(str) {
const matches = str.match(regex);
return matches.map((m) => JSON.parse(m));
}
console.log(jsonFromString(`some text {"val}ue": "something:some{thing"} and "teststri\\"n{g" some more other text [{"testa": 5, "testb": "t\\"\\"est6"}, {"testc": "1", "testd": "test45678"}, "teste", {"testf": {"testg": true, "testh": false}}] other extra added text {"somenumber": 14} "somestring"`)); //it can detect the json correctly even if you have other brackets or escaped quotation marks (\") inside of the strings.
Here is an even better version of this that uses a custom JSONParse() function to parse the JSON while also keeping Infinity, -Infinity, Undefined, NaN, and Null values:
function JSONParse(JSONString, keepUndefined = true){
let g = [];
let h = [];
let a = JSON.parse(JSONString.replace(/(?<="(?:\s*):(?:\s*))"{{(Infinity|NaN|-Infinity|undefined)}}"(?=(?:\s*)[,}](?:\s*))/g, '"{{\\"{{$1}}\\"}}"').replace(/(?<="(?:\s*):(?:\s*))(Infinity|NaN|-Infinity|undefined)(?=(?:\s*)[,}](?:\s*))/g, '"{{$1}}"'), function(k, v) {
if (v === '{{Infinity}}') return Infinity;
else if (v === '{{-Infinity}}') return -Infinity;
else if (v === '{{NaN}}') return NaN;
else if (v === '{{undefined}}') {g.push(k); if(keepUndefined){return v}else{undefined}};
h.push(k);
return v;
});
g.forEach((v, i)=>{
let b = Object.entries(a);
b[b.findIndex(b=>b[0]==v)]=[v, undefined];
a=Object.fromEntries(b)
});
{
let b = Object.entries(a);
!!b.filter(b=>String(b[1]).match(/^{{"{{(Infinity|NaN|-Infinity|undefined)}}"}}$/)).forEach((v, i)=>{
b[b.findIndex(b=>b[0]==v[0])]=[v[0], v[1].replace(/^(?:{{"{{)(Infinity|NaN|-Infinity|undefined)(?:}}"}})$/g, '{{$1}}')];
a=Object.fromEntries(b)
})
};
return a;
}
function JSONStringify(JSONObject, keepUndefined = false){
return JSON.stringify(JSONObject, function(k, v) {
if (v === Infinity) return "{{Infinity}}";
else if (v === -Infinity) return "{{-Infinity}}";
else if (Number.isNaN(v)) return "{{NaN}}";
else if (v === undefined && keepUndefined) return "{{undefined}}";
if(String(v).match(/^{{(Infinity|NaN|-Infinity|undefined)}}$/)){
v=v.replace(/^{{(Infinity|NaN|-Infinity|undefined)}}$/g, '{{"{{$1}}"}}')
}
return v;
}).replace(/(?<!\\)"{{(Infinity|NaN|-Infinity|undefined)}}"/g, '$1').replace(/(?<!\\)"{{\\"{{(Infinity|NaN|-Infinity|undefined)}}\\"}}"/g, '"{{$1}}"');
}
const jsonFromStringRegex = /([{\[]{1}([,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]|".*?")+[}\]]{1}|["]{1}(([^(")]|\\")*)+(?<!\\)["]){1}/gis;
function jsonFromString(str) {
const matches = str.match(jsonFromStringRegex);
return matches.map((m) => JSONParse(m, true));
}
function jsonStringsFromString(str) {
const matches = str.match(jsonFromStringRegex);
return matches.map((m) => m);
}//returns the substrings that were detected as json without parsing them
//example parsing all the JSON from the text
console.log(jsonFromString(`some text {"val}ue": "something:some{thing"} and "teststri\\"n{g" some more other text [{"testa": 5, "testb": "t\\"\\"est6"}, {"testc": "1", "testd": "test45678"}, "teste", {"testf": {"testg": true, "testh": false}}] other extra added text {"somenumber": 14, "someothernumber": Infinity, "another number": -Infinity, "somenullvalue": null, "someundefinedvalue": undefined, "someNaNvalue": NaN} "somestring"`)); //it can detect the json correctly even if you have other brackets or escaped quotation marks (\") inside of the strings.
//example stringifying all the JSON parsed from the text
console.log(JSONStringify(jsonFromString(`some text {"val}ue": "something:some{thing"} and "teststri\\"n{g" some more other text [{"testa": 5, "testb": "t\\"\\"est6"}, {"testc": "1", "testd": "test45678"}, "teste", {"testf": {"testg": true, "testh": false}}] other extra added text {"somenumber": 14, "someothernumber": Infinity, "another number": -Infinity, "somenullvalue": null, "someundefinedvalue": undefined, "someNaNvalue": NaN} "somestring"`)));
var a = JSON.parse('{"name":"John"}');
a ==> Object {name: "John"}
var b = [];
b.push(a);
本文标签: javascriptHow do I extract JSON objects from a string and add them to an arrayStack Overflow
版权声明:本文标题:javascript - How do I extract JSON objects from a string and add them to an array? - Stack Overflow 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/questions/1745620950a2159567.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论