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!
]
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.
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);
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 + "]";
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);
Related
I'm trying to get an array of JSON objects. To do that, I'm trying to make the input I have parsable, then parse it and push it to that array using a for loop. The inputs I have to work with look like this:
firstname: Chris, lastname: Cheshire, email: chris#cmdcheshire.com, viewerlink: audiencematic.com/viewer?v\u003dTESTSHOW\u0026push\u003d8A043B5A, tempid: 8A043B5A, permaid: F8tGYNx, showid: TESTSHOW
I've gotten it to the point where each loop produces something like this:
{ "firstname": First Name, "lastname": Last Name, "email": sample#gmail.com, "viewerlink": audiencematic.com/viewer?v=TESTSHOW&push=715B3074, "tempid": 715B3074, "permaid": F8tGYNx, "showid": TESTSHOW }
But got stuck on the last bit, making the values strings. I want it to look like this, so I can use JSON.parse():
{ "firstname": "First Name", "lastname": "Last Name", "email": "sample#gmail.com", "viewerlink": "audiencematic.com/viewer?v=TESTSHOW&push=715B3074", "tempid": "715B3074", "permaid": "F8tGYNx", "showed": "TESTSHOW" }
I tried a couple of different methods I found on here, but one of the values is a URL and the period is screwing with the replace expressions. I tried using the replace function like this:
var jsonStr2 = jsonStr.replace(/(: +\w)|(:+\w)/g, function(matchedStr) {
return ':"' + matchedStr.substring(2, matchedStr.length) + '"';
});
But it just becomes this:
{ "firstname":""irst Name, "lastname":""ast Name, "email":""ample#gmail.com, "viewerlink":""udiencematic.com/viewer?v=TESTSHOW&push=715B3074, "tempid":""15B3074, "permaid":""8tGYNx, "showid":""ESTSHOW }
How should I change my replace function?
(I tried that code because I'm using
var jsonStr = string.replace(/(\w+:)|(\w+ :)/g, function(matchedStr) {
return '"' + matchedStr.substring(0, matchedStr.length - 1) + '":';
});
to put parenthesis around the key sides and that seems to work.)
FIGURED IT OUT!! SEE MY ANSWER BELOW.
One option might be to try using a deserialized version of the string, alter the values associated with the properties of the object, and then convert back to a string.
var person = "{fname:\"John\", lname:\"Doe\", age:25}";
var obj = JSON.parse(person);
for (x in obj) {
obj[x] = "";
}
var result = JSON.stringify(obj);
It's a little longer than doing a string replacement, but I find it a little easier to follow.
I figured it out! I just had to mess around in regexr to figure out what conditions I needed. Here's the working for loop code:
for (i = 0; i < audiencelistdirty.feed.openSearch$totalResults.$t; i++) {
var string = '{ ' + audiencelistdirty.feed.entry[i].content.$t + ' }';
var jsonStr = string.replace(/(\w+:)|(\w+ :)/g, function(matchedStr) {
return '"' + matchedStr.substring(0, matchedStr.length - 1) + '":';
});
var jsonStr1 = jsonStr.replace(/(:(.*?),)|(:\s(.*?)\s)/g, function(matchedStr) {
return ':"' + matchedStr.substring(2, matchedStr.length - 1) + '",';
});
var jsonStr2 = jsonStr1.replace(/(",})/g, function(matchedStr) {
return '" }';
});
var newObj = JSON.parse(jsonStr2);
audiencelist.push(newObj);
};
It's pretty ugly but it works.
EDIT: Sorry, I completely misread the question. To replace the values with quoted strings use this regex replace function:
const str =
'firstname: Chris, lastname: Cheshire, email: chris#cmdcheshire.com, viewerlink: audiencematic.com/viewer?v\u003dTESTSHOW\u0026push\u003d8A043B5A, tempid: 8A043B5A, permaid: F8tGYNx, showid: TESTSHOW'
const json = (() => {
const result = str
.replace(/\w+:\s(.*?)(?:,|$)/g, function (match, subStr) {
return match.replace(subStr, `"${subStr}"`)
})
.replace(/(\w+):/g, function (match, subStr) {
return match.replace(subStr, `"${subStr}"`)
})
return '{' + result + '}'
})()
Wrap the input string into commas then use a regex to identify the keys (between , and :) and their associated values (between : and ,) and construct the object directly as in the example below:
const input = ' firstname : Chris , lastname: Cheshire, email: chris#cmdcheshire.com, viewerlink: audiencematic.com/viewer?v\u003dTESTSHOW\u0026push\u003d8A043B5A, tempid: 8A043B5A, permaid: F8tGYNx, showid: TESTSHOW ';
const wrapped = `,${input},`;
const re = /,\s*([^:\s]*)\s*:\s*(.*?)\s*(?=,)/g;
const obj = {}
Array.from(wrapped.matchAll(re)).forEach((match) => obj[match[1]] = match[2]);
console.log(obj)
String.matchAll() is a newer function, not all JavaScript engines have implemented it yet. If you are one of the unlucky ones (or if you write code to be executed in a browser) then you can use the old-school way:
const input = ' firstname : Chris , lastname: Cheshire, email: chris#cmdcheshire.com, viewerlink: audiencematic.com/viewer?v\u003dTESTSHOW\u0026push\u003d8A043B5A, tempid: 8A043B5A, permaid: F8tGYNx, showid: TESTSHOW ';
const wrapped = `,${input},`;
const re = /,\s*([^:\s]*)\s*:\s*(.*?)\s*(?=,)/g;
const obj = {}
let match = re.exec(wrapped);
while (match) {
obj[match[1]] = match[2];
match = re.exec(wrapped);
}
console.log(obj);
The anatomy of the regex used above
The regular expression piece by piece:
/ # regex delimiter; not part of the regex but JavaScript syntax
, # match a comma
\s # match a white space character (space, tab, new line)
* # the previous symbol zero or more times
( # start the first capturing group; does not match anything
[ # start a character class...
^ # ... that matches any character not listed inside the class
: # ... i.e. any character but semicolon...
\s # ... and white space character
] # end of the character class; the entire class matches only one character
* # the previous symbol zero or more times
) # end of the first capturing group; does not match anything
\s*:\s* # zero or more spaces before and after the semicolon
( # start of the second capturing group
.* # any character, any number of times; this is greedy by default
? # make it not greedy
) # end of the second capturing group
\s* # zero or more spaces
(?= # lookahead positive assertion; matches but does not consume the matched substring
, # matches a comma
) # end of the assertion
/ # regex delimiter; not part of the regex but JavaScript
g # regex flag; 'g' for 'global' is needed to find all matches
Read about the syntax of regular expressions in JavaScript. For a more comprehensive description of the regex patterns I recommend reading the PHP documentation of PCRE (Perl-Compatible Regular Expressions).
You can see the regex in action and play with it on regex101.com.
How can I replace a newline in a string with a ','? I have a string that is read from a file:
const fileText = (<FileReader>fileLoadedEvent.target).result.toString();
file.readCSV(fileText);
It takes a string from a file:
a,b,c,d,e,f
,,,,,
g,h,i,j,k,l
I'm able to detect the newline with this:
if (char === '\n')
But replacing \n like this doesn't work
str = csvString.replace('/\n/g');
I want to get the string to look like this:
a,b,c,d,e,f,
,,,,,,
g,h,i,j,k,l,
You can add , at end of each line like this
$ - Matches end of line
let str = `a,b,c,d,e,f
,,,,,
g,h,i,j,k,l`
let op = str.replace(/$/mg, "$&"+ ',')
console.log(op)
Try replacing the pattern $ with ,, comma:
var input = 'a,b,c,d,e,f';
input = input.replace(/$/mg, ",");
console.log(input);
Since you intend to retain the newlines/carriage returns, we can just take advantage of $ to represent the end of each line.
let text = `a,b,c,d,e,f
,,,,,
g,h,i,j,k,l`;
let edited = text.replace(/\s+/g, '');
console.log( edited )
You can try this solution also. \s means white spaces.
You may try out like,
// Let us have some sentences havin linebreaks as \n.
let statements = " Programming is so cool. \n We love to code. \n We can built what we want. \n :)";
// We will console it and see that they are working fine.
console.log(statements);
// We may replace the string via various methods which are as follows,
// FIRST IS USING SPLIT AND JOIN
let statementsWithComma1 = statements.split("\n").join(",");
// RESULT
console.log("RESULT1 : ", statementsWithComma1);
// SECOND IS USING REGEX
let statementsWithComma2 = statements.replace(/\n/gi, ',');
// RESULT
console.log("RESULT2 : ", statementsWithComma2);
// THIRS IS USING FOR LOOP
let statementsWithComma3 = "";
for(let i=0; i < statements.length; i++){
if(statements[i] === "\n")
statementsWithComma3 += ','
else
statementsWithComma3 += statements[i]
}
// RESULT
console.log("RESULT3 : ", statementsWithComma3);
I believe in some systems newline is \r\n or just \r, so give /\r?\n|\r/ a shot
var str = '{"Language":"en","Type":"General","Text":""Mela" means "apple" in Italian"}';
Now JSON.parse(str) throws this error
Uncaught SyntaxError: Unexpected token M in JSON at position 43
Now replacing quotes escapes whole string and parsed JSON is not usable anymore
str = str.replace(/\\([\s\S])|(")/g,"\\$1$2");
"{\"Language\":\"en\",\"Type\":\"General\",\"Text\":\"\"Mela\" means \"apple\" in Italian\"}"
Other solutions like below do not seem to be working in this scenario
How to escape a JSON string containing newline characters using JavaScript?
You need to add a backslash before each double quote within your string as:
const str = '{"Language":"en","Type":"General","Text": "\\"Mela\\" means \\"apple\\" in Italian"}';
const obj = JSON.parse(str)
console.log(obj.Text)
In JSON you don't escape double quotes of the property name or the begging of the property value, just escape what's inside property value:
{\"Text\":\"\"Mela\" means ....
It should be like this:
{"Text":"\"Mela\" means ....
This can be done with multiple replacements:
var str = '{"Language":"en","Type":"General","Text":""Mela" means "apple" in Italian"}';
str = str.replace(/"/,"'"); //Replace all " with '
str = str.replace(/{'/,'{"') //Restore " to start of JSON
str = str.replace(/','/,'","'); //Restore " around JSON , separators
str = str.replace(/':'/,'":"'); //Restore " around JSON : separators
str = str.replace(/'}/,'"}'); //Restore " to end of JSON
str = str.replace(/'/,'\"'); //All remaining ' must be inside of data, so replace with properly escaped \"
console.log(str);
EDIT: A problem with this solution is that is will also replace original ' characters with " inside the text.
I have dynamically generated JSON file with data. Some of the data generate error of an invalid json:
SyntaxError: JSON.parse: bad control character in string literal at line 34447 column 24 of the JSON data
I located problems and some of these are
"live_href": "http:// http://google.com",
or
"login_pass": "bourdfthuk.midas.admin r3adqerds7one",
I already fixed whitespace at the beginning and end with .trim() but trim won't remove whitespace in the center of a string.
Use this
str.replace(/\s/g,'')
The g repeats for all whitespace instances and the s is for all white spaces and not just the literal characters.
I see what you are trying to do. In that case, you will have to loop through your string like so:
var word = "North Dakota Blah blah";
word = word.split(' ');
for (var x = 0; x < word.length; x++) {
if (word[x] === "") {
word.splice(x, 1);
x--;
}
}
word = word.join(' ');
console.log(word);
Working example: https://jsfiddle.net/85sj4ay6/2/
As someone already mentioned, your json is invalid, so you therefore cannot parse it into JSON. However, if it was valid, it would essentially work like this:
var myJson = {"login_pass": "bourdfthuk.midas.admin r3adqerds7one"};
myJson.login_pass = myJson.login_pass.replace(/ /g, '');
console.log(myJson);
Working example: https://jsfiddle.net/85sj4ay6/
I parse the data from website and try to change to a json object.
Here is my function:
function outPutJSON() {
for (var i = 0; i < movieTitle.length; i++) {
var handleN = movieContent[i];
console.log('===\n');
console.log(handleN);
data.movie.push({
mpvieTitle: movieTitle[i],
movieEnTitle: movieEnTitle[i],
theDate: theDate[i],
theLength: theLength[i],
movieVersion: movieVersion[i],
youtubeId: twoId[i],
content: movieContent[i]
});
};
return JSON.stringify(data);
}
console.log will print movieContent[0] like:
but i return JSON.stringfy(data);
it will become:
There are so many /n i want to remove it.
I try to change return JSON.stringfy(data); to this:
var allMovieData = JSON.stringify(data);
allMovieData = allMovieData.replace(/\n/g, '');
return allMovieData;
It's not working the result is the same.
How to remove /n when i use JSON.stringfy() ?
Any help would be appreciated . Thanks in advance.
In your data screenshots, you literally see "\n".
This probably means that the actual string doesn't contain a newline character (\n), but a escaped newline character (\\n).
A newline character would have been rendered as a linebreak. You wouldn't see the \n.
To remove those, use .replace(/\\n/g, '') instead of .replace(/\n/g, '')
just :=>
JSON.stringify(JSON.parse(<json object>))
JSON.stringify converts new lines (\n) and tab (\t) chars into string, so, when you will try to parse it, the string will contain those again.
So, you need to search the string \n, you can do that with something like that.
const stringWithNewLine = {
x: `this will conatin
new lines`
};
const json = JSON.stringify(stringWithNewLine);
console.log(json.replace(/\\n/g, ''))
I know this is an old question but it is always good to have options. You can use a string literal as a simple wrapper. The string literal will honor the string's line breaks, empty spaces etc. Like:
let jsonAsPrettyString = `${JSON.stringify(jsonObject, null, 2)}`;