21

This JSON data is being dynamically inserted into a template I'm working on. I'm trying to remove the trailing comma from the list of objects.

The CMS I'm working in uses Velocity, which I'm not too familiar with yet. So I was looking to write a snippet of JavaScript that detects that trailing comma on the last object (ITEM2) and removes it. Is there a REGEX I can use to detect any comma before that closing bracket?

[
    {
        "ITEM1":{
            "names":[
            "nameA"
            ]
        }
    },
    {
        "ITEM2":{
            "names":[
            "nameB",
            "nameC"
            ]
        }
    }, // need to remove this comma!
]
2
  • 7
    it's not legal JSON - whatever produced it needs fixing. Not fixing that will just accrue technical debt for the next user of that output. Commented Dec 17, 2015 at 21:15
  • ,\s*\] should do, but doesn't care about string literals. Commented Dec 17, 2015 at 21:15

7 Answers 7

43

You need to find ,, after which there is no any new attribute, object or array.
New attribute could start either with quotes (" or ') or with any word-character (\w).
New object could start only with character {.
New array could start only with character [.
New attribute, object or array could be placed after a bunch of space-like symbols (\s).

So, the regex will be like this:

const regex = /\,(?!\s*?[\{\[\"\'\w])/g;

Use it like this:

// javascript
const json = input.replace(regex, ''); // remove all trailing commas (`input` variable holds the erroneous JSON)
const data = JSON.parse(json); // build a new JSON object based on correct string

Try the first regex.


Another approach is to find every ,, after which there is a closing bracket.
Closing brackets in this case are } and ].
Again, closing brackets might be placed after a bunch of space-like symbols (\s).

Hence the regexp:

const regex = /\,(?=\s*?[\}\]])/g;

Usage is the same.

Try the second regex.

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

3 Comments

This also replaces comma's inside strings, e.g. {"letters" : "a, b, c"}. The following just checks against trailing commas: fix.replace(/(.*?),\s*(\}|])/g, "$1$2");
@bob That statement requires an *. The code provided still removes a comma in string context given the following JSON { "chars": "1,2,3,},]" }. The resulting output would be { "chars": "1,2,3}]" }. This scenario is less common, so it's an improvement, but depending on the context this might or might not be an issue.
More generally, you will always have false positives in this case, because a JSON can contain another JSON (which can contain another JSON, and so on). That's why the issue must be dealt with on the generation stage: don't produce malformed JSON, and assume that if the input is a JSON, it is valid.
3

Consider the Json input = [{"ITEM1":{"names":["nameA"]}},{"ITEM2":{"names":["nameB","nameC"]}},] without whitespaces. I suggest a simple way using substring.

input = input.substring(0, input.length-2);
input = input + "]";

Comments

1

For your specific example, you can do a simple search/replace like this:

,\n]$

Replacement string:

\n]

Working demo

Code

var re = /,\n]$/; 
var str = '[  \n   {  \n      "ITEM1":{  \n         "names":[  \n            "nameA"\n         ]\n      }\n   },\n   {  \n      "ITEM2":{  \n         "names":[  \n            "nameB",\n            "nameC"\n         ]\n      }\n   },\n]';
var subst = '\n]'; 

var result = str.replace(re, subst);

Comments

1

For the general case where you need to process JSON that is malformed in ways that are otherwise accepted as JavaScript, the JSON5 library works great. It would work for this specific case as well.

See https://www.npmjs.com/package/json5

Once used in your project, the trailing comma would be handled by a single call like so:

input = JSON5.parseText(input)

Comments

0

I developped a simple but useful logic for this purpose - you can try this.

Integer Cnt = 5;
        String StrInput = "[";
        
        for(int i=1; i<Cnt; i++){
            StrInput +="   {"  
                     + "     \"ITEM"+i+"\":{ " 
                     + "      \"names\":["  
                              + "   \"nameA\""
                                + "]"
                  +"}";
                            
            if(i ==(Cnt-1)) { 
                StrInput += "}";            
            } else {
                StrInput += "},";
            }
        
        }
        StrInput +="]";
        
        System.out.println(StrInput);

Comments

0

You can remove trailing commas in a complex json string using regular expression

  const regex = /,\s*([\]}])/g;
  const fixedJson = jsonString.replace(regex, "$1");
  const json = JSON.parse(fixedJson);
``

Comments

0

The proposed regex approaches have a problem. If the JSON string you want to normalize is

var jstring = '{"a":"5,}", "z":{"x":2,}, "b":4,}';

then applying jstring.replace(regex, '') will also remove the comma after 5 in the string jstring.a = "5,}". This is not desirable.

Another approach, not resorting to regex, is:

eval(`var result=${jstring}`)
JSON.stringify(result)

1 Comment

I would expect that the wrong json string is from some source, not part of the application. In that case, never use eval. If it's in the application, then fix the string

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.