3

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

Regexper

2
  • Doubt this is actually possible without writing your own JSON parser that is aware of the particular syntax that would cause JSON.parse to throw. The biggest problem is the nesting. Commented Nov 16, 2016 at 15:07
  • Are the probably-invalid parts well-defined? I mean for example if you know that any kind of invalid stuff comes from a %...% expression inside the json as value of some property. Commented Nov 16, 2016 at 15:36

1 Answer 1

3

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*{/

Sign up to request clarification or add additional context in comments.

3 Comments

Quite interesting idea, and probably more stable.
@kirill.buga yes, and also less work than writing a custom json parser grammar :)
I'm also thinking about commas at the beginning\end of the object.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.