JSON.stringify / parse oddness with quote marks - javascript

I am running into an odd little problem with parsing some JSON which has quotes in it. I am using the native JSON.stringify and JSON.parse functions to do this. If I stringify an object which an object which has quote marks in it, they are escaped as one would expect. If I then parse this back into an object, it again works fine.
The problem is occurring where I stringify, then print the object to a page, then parse the resulting string. If I try to do this, the parse function fails as stringify has only put single slashes before each of the offending quote marks.
The reason I need to achieve this is I am working on an application that dynamically loads content stored in a database as JSON strings. The strings at some point need to be printed onto the page somewhere so that the javascript can find them and build the page based on their contents. I need some way of robustly passing the object into and out of strings which will not fail if a user inputs the wrong characters!
I can solve this for the moment by inserting extra slashes into the code with a replace call, but I was wondering if there is a better way to handle this?
I have put together a couple of jsfiddles to illustrate what I am trying to describe:
http://jsfiddle.net/qwUAJ/ (Stringify then parse back)
var ob = {};
ob["number1"] = 'Number "1"';
ob["number2"] = 'Number 2';
ob["number3"] = 'Number 3';
var string = JSON.stringify(ob);
var reOb = JSON.parse('{"number1":"Number \"1\"","number2":"Number 2","number3":"Number 3"}');
$('div').html(string);
http://jsfiddle.net/a3gBf/4/ (Stringify, then print, then parse back)
// Make an object
var ob = {};
ob["number1"] = 'Number "1"';
ob["number2"] = 'Number 2';
ob["number3"] = 'Number 3';
// Turn the object into a JSON string
var string = JSON.stringify(ob);
// Printing the string outputs
// {"number1":"Number \"1\"","number2":"Number 2","number3":"Number 3"}
$('.stringified').html(string);
// Attempt to turn the printed string back into an object
var reOb = JSON.parse('{"number1":"Number \"1\"","number2":"Number 2","number3":"Number 3"}');
// This fails due to the single escaped quote marks.
Thank you for any help in advance!

This is a problem which arises from re-evaluating a String without first converting it back into a string literal, so the meaning changes if it is even still valid.
You need to consider what does '\"' as a literal actually mean? The answer is ", without the \. Why?
\" resolves to "
If you want to have \" as the result of the literal, you need to write '\\\"'
\\ resolves to \
\" resolves to "
So basically, the extra slashes are required to escape any characters with special meaning in string literals.
If you did var reOb = JSON.parse($('.stringified').html()); it would work fine as is.
Consider further
str = '\\\"\\\''; // \"\'
str = '\"\''; // "'
str = '"''; // SyntaxError: Unexpected token ILLEGAL
As far as I'm aware, JavaScript offers no native implementation to convert strings as desired, so the easiest method I know of is using a replace
function toLiteral(str) {
var dict = {'\b': 'b', '\t': 't', '\n': 'n', '\v': 'v', '\f': 'f', '\r': 'r'};
return str.replace(/([\\'"\b\t\n\v\f\r])/g, function ($0, $1) {
return '\\' + (dict[$1] || $1);
});
}
toLiteral('foo\\bar'); // "foo\\bar"

If you generate JS with PHP code you should escape the quotes in your JSON string:
//PHP code generating js code
echo "var myJSONString = \"". str_replace("\"","\\\"",$mySqlJSON)."\";";

Related

Why the .replace() and toUppercase() did not work in the second function? [duplicate]

I want to replace the smart quotes like ‘, ’, “ and ” to regular quotes. Also, I wanted to replace the ©, ® and ™. I used the following code. But it doesn't help.
Kindly help me to resolve this issue.
str.replace(/[“”]/g, '"');
str.replace(/[‘’]/g, "'");
Use:
str = str.replace(/[“”]/g, '"');
str = str.replace(/[‘’]/g, "'");
or to do it in one statement:
str = str.replace(/[“”]/g, '"').replace(/[‘’]/g,"'");
In JavaScript (as in many other languages) strings are immutable - string "replacement" methods actually just return the new string instead of modifying the string in place.
The MDN JavaScript reference entry for replace states:
Returns a new string with some or all matches of a pattern replaced by a replacement.
…
This method does not change the String object it is called on. It simply returns a new string.
replace return the resulting string
str = str.replace(/["']/, '');
The OP doesn't say why it isn't working, but there seems to be problems related to the encoding of the file. If I have an ANSI encoded file and I do:
var s = "“This is a test” ‘Another test’";
s = s.replace(/[“”]/g, '"').replace(/[‘’]/g,"'");
document.writeln(s);
I get:
"This is a test" "Another test"
I converted the encoding to UTF-8, fixed the smart quotes (which broke when I changed encoding), then converted back to ANSI and the problem went away.
Note that when I copied and pasted the double and single smart quotes off this page into my test document (ANSI encoded) and ran this code:
var s = "“This is a test” ‘Another test’";
for (var i = 0; i < s.length; i++) {
document.writeln(s.charAt(i) + '=' + s.charCodeAt(i));
}
I discovered that all the smart quotes showed up as ? = 63.
So, to the OP, determine where the smart quotes are originating and make sure they are the character codes you expect them to be. If they are not, consider changing the encoding of the source so they arrive as “ = 8220, ” = 8221, ‘ = 8216 and ’ = 8217. Use my loop to examine the source, if the smart quotes are showing up with any charCodeAt() values other than those I've listed, replace() will not work as written.
To replace all regular quotes with smart quotes, I am using a similar function. You must specify the CharCode as some different computers/browsers default settings may identify the plain characters differently ("",",',').
Using the CharCode with call the ASCII character, which will eliminate the room for error across different browsers, and operating systems. This is also helpful for bilingual use (accents, etc.).
To replace smart quotes with SINGLE QUOTES
function unSmartQuotify(n){
var name = n;
var apos = String.fromCharCode(39);
while (n.indexOf("'") > -1)
name = name.replace("'" , apos);
return name;
}
To find the other ASCII values you may need. Check here.

replace multiple words in string based on an array [duplicate]

I want to replace the smart quotes like ‘, ’, “ and ” to regular quotes. Also, I wanted to replace the ©, ® and ™. I used the following code. But it doesn't help.
Kindly help me to resolve this issue.
str.replace(/[“”]/g, '"');
str.replace(/[‘’]/g, "'");
Use:
str = str.replace(/[“”]/g, '"');
str = str.replace(/[‘’]/g, "'");
or to do it in one statement:
str = str.replace(/[“”]/g, '"').replace(/[‘’]/g,"'");
In JavaScript (as in many other languages) strings are immutable - string "replacement" methods actually just return the new string instead of modifying the string in place.
The MDN JavaScript reference entry for replace states:
Returns a new string with some or all matches of a pattern replaced by a replacement.
…
This method does not change the String object it is called on. It simply returns a new string.
replace return the resulting string
str = str.replace(/["']/, '');
The OP doesn't say why it isn't working, but there seems to be problems related to the encoding of the file. If I have an ANSI encoded file and I do:
var s = "“This is a test” ‘Another test’";
s = s.replace(/[“”]/g, '"').replace(/[‘’]/g,"'");
document.writeln(s);
I get:
"This is a test" "Another test"
I converted the encoding to UTF-8, fixed the smart quotes (which broke when I changed encoding), then converted back to ANSI and the problem went away.
Note that when I copied and pasted the double and single smart quotes off this page into my test document (ANSI encoded) and ran this code:
var s = "“This is a test” ‘Another test’";
for (var i = 0; i < s.length; i++) {
document.writeln(s.charAt(i) + '=' + s.charCodeAt(i));
}
I discovered that all the smart quotes showed up as ? = 63.
So, to the OP, determine where the smart quotes are originating and make sure they are the character codes you expect them to be. If they are not, consider changing the encoding of the source so they arrive as “ = 8220, ” = 8221, ‘ = 8216 and ’ = 8217. Use my loop to examine the source, if the smart quotes are showing up with any charCodeAt() values other than those I've listed, replace() will not work as written.
To replace all regular quotes with smart quotes, I am using a similar function. You must specify the CharCode as some different computers/browsers default settings may identify the plain characters differently ("",",',').
Using the CharCode with call the ASCII character, which will eliminate the room for error across different browsers, and operating systems. This is also helpful for bilingual use (accents, etc.).
To replace smart quotes with SINGLE QUOTES
function unSmartQuotify(n){
var name = n;
var apos = String.fromCharCode(39);
while (n.indexOf("'") > -1)
name = name.replace("'" , apos);
return name;
}
To find the other ASCII values you may need. Check here.

Remove the javascript object variable name text from json code

I have a String variable that stores the literal text of a JavaScript object:
String jsString = "mainData = {"name":"John", "id":"12345"}"
Is there a JSON method (or any method) in Java that will remove the "mainData = " part of the string in order to leave only the JavaScript data? Something like this:
newString = someMethod(jsString);
JSONObject jsonObject = new JSONObject(newString); //newString = "{"name":"John", "id":"12345"}"
There's String#replaceFirst:
jsString = jsString.replaceFirst("^[^{]+", "");
Live Example
That will remove any characters as the start of the string prior to the first {. It makes the assumption that the string contains JSON where the outermost thing is an object (as opposed to an array or just a value), although it could readily be tweaked not to make that assumption. For instance, this version:
jsString = jsString.replaceFirst("^\\s*[A-Za-z0-9_$]+\\s*=\\s*", "");
Live Example
That removes a series of letters, numbers, _, or $, optionally surrounded by whitespace, and a following =, possibly followed by whitespace, at the beginning of the string. Now, that's not a complete list of valid JavaScript identifier characters (that list is long), but you get the idea.

How do JSON.parse() and escape characters work in JavaScript?

Suppose I have an object variable:
var obj = {
key: '\"Hello World\"'
}
Then I tried parse it to string by using JSON.stringify in Chrome devtools console:
JSON.stringify(obj) // "{"key":"\"Hello World\""}"
I get the result "{"key":"\"Hello World\""}". Then I give it to a string
var str = '{"key":"\"Hello World\""}'
At least I try to convert it back to obj:
JSON.parse(str);
but the browser tell me wrong Uncaught SyntaxError
What confused me is why this is wrong? I get the string from an origin object and I just want turn it back.
How can I fix this problem? If I want do the job like convert obj to string and return it back, how can I do?
You're tried to convert your JSON into a string literal by wrapping it in ' characters, but \ characters have special meaning inside JavaScript string literals and \" gets converted to " by the JavaScript parser before it reaches the JSON parser.
You need to escape the \ characters too.
var str = '{"key":"\\"Hello World\\""}'
That said, in general, it is better to not try to embed JSON in JavaScript string literals only to parse them with JSON.parse in the first place. JSON syntax is a subset of JavaScript so you can use it directly.
var result = {"key":"\"Hello World\""};
try:
var str = '{"key":"\\"Hello World\\""}';

JSON.stringify escapes double quotes every time when stringified

I am storing JSON objects retreived from web service to objects in javascript. In many places this gets stringified(This obj goes through some plugins and it strigifies and stores it and retreives it) and it adds multiple slashes. How can I avoid it ?
http://jsfiddle.net/MJDYv/2/
var obj = {"a":"b", "c":["1", "2", "3"]};
var s = "";
console.log(obj);
s = JSON.stringify(obj);
alert(s); // Proper String
s = JSON.stringify(s);
alert(s); // Extra slash added, Quotes are escaped
s = JSON.stringify(s);
alert(s); // Again quotes escaped or slash escaped but one more slash gets added
var obj2 = JSON.parse(s);
console.log(obj2); // Still a String with one less slash, not a JSON object !
So when parsing this multiple string I end up with a string again. And when tried to access like an object it crashes.
I tried to remove slash by using replace(/\\/g,"") but I end with this : ""{"a":"b","c":["1","2","3"]}""
What did you expect to happen?
JSON.stringify does not act like an "identity" function when called on data that has already been converted to JSON. By design, it will escape quote marks, backslashes, etc.
You need to call JSON.parse() exactly as many times as you called JSON.stringify() to get back the same object you put in.
Try
JSON.stringify(s).replace(/\\"/g, '"')
You can avoid that simply by calling JSON.stringify() exactly once on the data you want turn into JSON.
Try this:
s = {"a":"b", "c":["1", "2", "3"]}
JSON.stringify(JSON.stringify(s))
gives the output as
'"{\"a\":\"b\",\"c\":[\"1\",\"2\",\"3\"]}"'

Categories

Resources