How to convert an invalid json into a valid json so that it could be parsed

Viewed 590

I have an invalid json coming from front end which I have no control. The json is like this:

{
    "assetClassDetails":[{}],
    "assetClassRequired":null,
    "baseUnitofMeasure":"PMI",
    "bomParent":"Yes",
    "commodityCodeTaric":"84158200",
    "enLanguageKey":"EN",
    "enMaterialLongText":"Lenovo Privacy Filter for 14" Notebooks ( L, T and X1 Carbon)"",
    "grossWeightInKg":null,
    "height":null,
    "heightLengthWidthUnit":null,
    "length":null,"manufacturerPartNumber":"",
    "materialLongDescription":"Lenovo Privacy Filter for 14" Notebooks ( L, T and X1 Carbon)"",
    "physicalCategory":"Physical",
    "volume":null,
    "volumeUnit":null,
    "width":null,
    "xxLanguageKey":null,
    "xxMaterialLongText":null
 }

Pl. look at enMaterialLongText & materialLongDescription. I have decided to split the whole string on comma character. But here comma is not only key-value pair delimiter, it is also there inside some values. So I used a regex like this:

test = test.replaceAll("(,)[\\s]*([^\"])", "_COMMA_ $2");

That works. Now I need another regex so that nested quotes can be converted to string such as "QUOTE". After Gson has parsed the json into java object, I can convert properties like enMaterialLongText & materialLongDescription to escaped quote mark.

1 Answers

If keys and values are not formatted as in the question, arbitrarily, you can't fix the JSON on your end, it should be fixed on the provider's side.

Assuming the key-value pairs are on separate lines you may use

StringBuffer fixedJSON = new StringBuffer();
Matcher m = Pattern.compile("(?<=\":\").*(?=\")").matcher(text);
while (m.find()) {
    m.appendReplacement(fixedJSON, m.group().replace("\"", "_QUOTE_"));
}
m.appendTail(fixedJSON);
System.out.println(fixedJSON.toString()); 

The (?<=\":\").*(?=\") regex matches values located after ":" till the last " like this:

  • (?<=\":\") - a positive lookbehind that requires a ":" immediately to the left of the current location
  • .* - any zero or more chars other than line break chars as many as possible
  • (?=\") - a positive lookahead that requires a " immediately to the right of the current location.
Related