Reputation: 1159
Given I have a string which represents JSON object. It might be invalid, as there might be some params which will be replaced by another system (e.g. %param%). I need to remove all objects with known propertyName equal to "true" using regex.
{
"someTopLevelProp": "value",
"arrayOfData": [
{
"firstPropIAlwaysKnow": "value",
"dontCareProp": $paramValue$,
"dontCareProp2": 2,
"flagWhichShouldIUse": true,
"somethingAtTheEnd": "value"
},
{
"absolutelyAnotherObject": %paramValue%
},
{
"firstPropIAlwaysKnow": "value",
"dontCareProp": "value",
"dontCareProp2": 2,
"flagWhichShouldIUse": false,
"somethingAtTheEnd": "value"
},
{
"firstPropIAlwaysKnow": "value",
"dontCareProp": "value",
"dontCareProp2": 2,
"flagWhichShouldIUse": true,
"somethingAtTheEnd": "value"
}
]
}
In the example above, I always have "firstPropIAlwaysKnow" which means that object can contain flag which I need. After that there might be other properties. But the most important here is "flagWhichShouldIUse" prop, which mean this object should be removed (but only in case when value equal to 'true'). As result I should receive:
{
"someTopLevelProp": "value",
"arrayOfData": [
{
"absolutelyAnotherObject": %paramValue%
},
{
"firstPropIAlwaysKnow": "value",
"dontCareProp": "value",
"dontCareProp2": 2,
"flagWhichShouldIUse": false,
"somethingAtTheEnd": "value"
}
]
}
My knowledge in regex are not strong enough, thus kindly ask for community's help.
P.S. Please do not mention that parsing JSON with regex it's crazy\incorrect\bad idea - be sure I know that.
ANSWER: now I have working regex which do that stuff. Thank you everyone who tried to help here. Maybe it will be useful for someone.
/{\s+?"firstPropIAlwaysKnow": "value"[^{}]+?(?:\{[^}]*\}[^}]+?)*[^}]+?"flagWhichShouldIUse": true[^}]+?},?/gi
Upvotes: 3
Views: 1650
Reputation: 21926
You really can't do this with just regular expressions. Something like this might work:
let filtered = jsonstring
// split into the individual 'objects'
// might need to modify this depending on formatting. You
// could use something like /},\s*{/ to split the string,
// but couldn't re-join with same formatting
.split('},{')
// filter for only the strings with the relevant property
// set to false
.filter(s => s.match(/"flagWhichShouldIUse":\s*false/) // again, may need to change
// put humpty-dumpty back together again
.join('},{');
The exact splitting method will depend heavily on the structure of your JSON, and this isn't fool-proof. It doesn't handle nesting properly. If your JSON is pretty-printed, you could use the number of tab/space characters as part of the splitter: this for instance would only split for one tab only: /\n\t},\s*{/
Upvotes: 3