Change single backslash in R character string to valid JSON string - json

I have a string in R which escapes quotation marks:
my_text = {\"stim\":[\"platery\",\"denial\",\"generic\"]}
When using cat() I get:
{"stim":["platery","denial","generic"]}
Now my whole string is a JSON string that needs to be parsed and is evaluated invalid by JSONLint. If I copy&paste the cat() version, this is valid a JSON, so I think I just miss some pre-processing here.
I saw this SO post here, and this one, and this really good one, so I tried to replace the single quotation marks with double quotation marks for the JSON parser:
gsub("\\\\", "\\\\\\\\", my_text, fixed=TRUE)
but it did't change my string as I wanted. How can I change the string to become valid JSON?

As Wiktor said your gsub didn't work because you are attempting to replace backslashes, but there aren't any backslashes in your string. R is just using the backslashes as a way to store the double quotes. The third SO post you link does a good job explaining R's string literals which addresses this. A backslash in R is stored as a double backslash.
My first piece of advice would be to use the R package jsonlite to construct your JSON from an R object as opposed to a string if possible (heres the vignette).
Example:
myJSON <- jsonlite::toJSON(list(stim=c("platery","denial","generic")))
# {"stim":["platery","denial","generic"]}
Second, (as the third SO post again does a good job of explaining) copying/pasting the print method of the string may not be the best way to validate the JSON. I'm not sure of the use case, but R storing the double quotes with escape characters is probably not a bad thing.
If you want to get a prettier print method you can use numerous tricks in R (noquote(), cat(), print(quote=F)) but this won't change that R stores the double quotes with backslashes:
Additionally, in some cases constructing the JSON isn't necessary. I have an API built using the plumbr package that returns a list as JSON without any modifications (recJSON <- list(message=messages,recommendations=list(name=names, link=URLs)))

Related

Fixind invalid json in SQL

I'm parsing json in redshift using json_extract_path_text, but this json is invalid (one of the fields contains double quote inside of the string value):
"somefield": "4 *\\"`)(z"
Is there any way to get rid of this quote and replace it with some other value (I do not really care about this particular data as it is wrong anyway, but I want to fetch some other parts of this json).
It looks like you have the wrong number of backslashes in the string. You need either or 1, to just get the double quotes, or 3 to get a backslash and the double quote. But this isn't really the question.
You can use the REPLACE() function to strip the \" text out. https://docs.aws.amazon.com/redshift/latest/dg/r_REPLACE.html
REPLACE(json_text, '\\"', '')
I believe REPLACE() doesn't do any string interpretation so no additional escaping will be needed.

Interpolating a JSON string removes JSON quotations

I have the following two lines of code:
json_str = _cases.to_json
path += " #{USER} #{PASS} #{json_str}"
When I use the debugger, I noticed that json_str appears to be formatted as JSON:
"[["FMCE","Wiltone","Wiltone","04/10/2018","Marriage + - DOM"]]"
However, when I interpolate it into another string, the quotes are removed:
"node superuser 123456 [["FMCE","Wiltone","Wiltone","04/10/2018","Marriage + - DOM"]]"
Why does string interpolation remove the quotes from JSON string and how can I resolve this?
I did find one solution to the problem, which was manually escaping the string:
json_str = _cases.to_json.gsub('"','\"')
path += " #{USER} #{PASS} \"#{json_str}\""
So basically I escape the double quotes generated in the to_json call. Then I manually add two escaped quotes around the interpolated variable. This will produce a desired result:
node superuser 123456 "[[\"FMCE\",\"Wiltone\",\"Wiltone\",\"04/10/2018\",\"Marriage + - DOM\"]]"
Notice how the outer quotes around the collection are not escaped, but the strings inside the collection are escaped. That will enable JavaScript to parse it with JSON.parse.
It is important to note that in this part:
json_str = _cases.to_json.gsub('"','\"')
it is adding a LITERAL backslash. Not an escape sequence.
But in this part:
path += " #{USER} #{PASS} \"#{json_str}\""
The \" wrapping the interpolated variable is an escape sequence and NOT a literal backslash.
Why do you think the first and last quote marks are part of the string? They do not belong to the JSON format. Your program’s behavior looks correct to me.
(Or more precisely, your program seems to be doing exactly what you told it to. Whether your instructions are any good is a question I can’t answer without more context.)
It's hard to tell with the small sample, but it looks like you might be getting quotes from your debugger output. assuming the output of .to_json is a string (usually is), then "#{json_str}" should be exactly equal to json_str. If it isn't, that's a bug in ruby somehow (doubtful).
If you need the quotes, you need to either add them manually or escape the string using whatever escape function is appropriate for your use case. You could use .to_json as your escape function even ("#{json_str.to_json}", for example).

converting JSON object in R to string representation gives \" rather than ". How to get rid of slash?

I need to get ride of the forward slash when converting a JSON object to a string. Why do I get \" rather than the double quote, and how can I show as just a double quote with the slash? Consider the example, d_json without slash, but slash appears when converted to string:
library(jsonlite)
d = data.frame(one=as.factor(c('a','a','b','b','c','c')),
two=c(1,2,3,4,5,6))
d_json <- toJSON(d)
d_json
##[{"one":"a","two":1},{"one":"a","two":2},{"one":"b","two":3},{"one":"b","two":4},{"one":"c","two":5},{"one":"c","two":6}]
toString(d_json)
##[1] "[{\"one\":\"a\",\"two\":1},{\"one\":\"a\",\"two\":2},{\"one\":\"b\",\"two\":3},{\"one\":\"b\",\"two\":4},{\"one\":\"c\",\"two\":5},{\"one\":\"c\",\"two\":6}]"
The slashes in the output you're seeing are just escape characters, and \" will count as one character. Check out str_sub(toString(d_json),3,3) and str_sub(toString(d_json),4,4) to see this effect on further string operations. As mentioned in hrbrmstr's comment, cat() shows how the final string will look when actually displayed.

Strip backslashes from encoded JSON response

Building a Json respose with erlang. First I construct the data in terms and then use jsx to convert it to JSON:
Response = jsx:term_to_json(MealsListResponse),
The response actually is valid JSON according to the validators I have used:
The problem is when parsing the response in the front end. Is there a way to strip the backslashes from the Erlang side, so that the will not appear on the payload response?
The backslashes are not actually part of the string. They're just used when the string is printed as a term - that is, in the same way you'd write it in an Erlang source file. This works in the same way as character escapes in strings in C and similar languages: inside double quotes, double quotes that should be part of the string need to be escaped with backslashes, but the backslashes don't actually make it into the string.
To print the string without character escapes, you can use the ~s directive of io:format:
io:format("~s~n", [Response]).
If you're sending the response over a TCP socket, all you need to do is converting the string to binary with an appropriate Unicode conversion. Most of the time you'll want UTF-8, which you can get with:
gen_tcp:send(MySocket, unicode:characters_to_binary(Response)).

How to escape special characters in building a JSON string?

Here is my string
{
'user': {
'name': 'abc',
'fx': {
'message': {
'color': 'red'
},
'user': {
'color': 'blue'
}
}
},
'timestamp': '2013-10-04T08: 10: 41+0100',
'message': 'I'mABC..',
'nanotime': '19993363098581330'
}
Here the message contains single quotation mark, which is same as the quotation used in JSON. What I do is fill up a string from user inputs such as message. So, I need to escape those kind of special scenarios which breaks the code. But other than string replace, is there any way to make them escape but still allow HTML to process them back to the correct message?
I'm appalled by the presence of highly-upvoted misinformation on such a highly-viewed question about a basic topic.
JSON strings cannot be quoted with single quotes. The various versions of the spec (the original by Douglas Crockford, the ECMA version, and the IETF version) all state that strings must be quoted with double quotes. This is not a theoretical issue, nor a matter of opinion as the accepted answer currently suggests; any JSON parser in the real world will error out if you try to have it parse a single-quoted string.
Crockford's and ECMA's version even display the definition of a string using a pretty picture, which should make the point unambiguously clear:
The pretty picture also lists all of the legitimate escape sequences within a JSON string:
\"
\\
\/
\b
\f
\n
\r
\t
\u followed by four-hex-digits
Note that, contrary to the nonsense in some other answers here, \' is never a valid escape sequence in a JSON string. It doesn't need to be, because JSON strings are always double-quoted.
Finally, you shouldn't normally have to think about escaping characters yourself when programatically generating JSON (though of course you will when manually editing, say, a JSON-based config file). Instead, form the data structure you want to encode using whatever native map, array, string, number, boolean, and null types your language has, and then encode it to JSON with a JSON-encoding function. Such a function is probably built into whatever language you're using, like JavaScript's JSON.stringify, PHP's json_encode, or Python's json.dumps. If you're using a language that doesn't have such functionality built in, you can probably find a JSON parsing and encoding library to use. If you simply use language or library functions to convert things to and from JSON, you'll never even need to know JSON's escaping rules. This is what the misguided question asker here ought to have done.
A JSON string must be double-quoted, according to the specs, so you don't need to escape '.
If you have to use special character in your JSON string, you can escape it using \ character.
See this list of special character used in JSON :
\b Backspace (ascii code 08)
\f Form feed (ascii code 0C)
\n New line
\r Carriage return
\t Tab
\" Double quote
\\ Backslash character
However, even if it is totally contrary to the spec, the author could use \'.
This is bad because :
It IS contrary to the specs
It is no-longer JSON valid string
But it works, as you want it or not.
For new readers, always use a double quotes for your json strings.
Everyone is talking about how to escape ' in a '-quoted string literal. There's a much bigger issue here: single-quoted string literals aren't valid JSON. JSON is based on JavaScript, but it's not the same thing. If you're writing an object literal inside JavaScript code, fine; if you actually need JSON, you need to use ".
With double-quoted strings, you won't need to escape the '. (And if you did want a literal " in the string, you'd use \".)
Most of these answers either does not answer the question or is unnecessarily long in the explanation.
OK so JSON only uses double quotation marks, we get that!
I was trying to use JQuery AJAX to post JSON data to server and then later return that same information.
The best solution to the posted question I found was to use:
var d = {
name: 'whatever',
address: 'whatever',
DOB: '01/01/2001'
}
$.ajax({
type: "POST",
url: 'some/url',
dataType: 'json',
data: JSON.stringify(d),
...
}
This will escape the characters for you.
This was also suggested by Mark Amery, Great answer BTW
Hope this helps someone.
May be i am too late to the party but this will parse/escape single quote (don't want to get into a battle on parse vs escape)..
JSON.parse("\"'\"")
The answer the direct question:
To be safe, replace the required character with \u+4-digit-hex-value
Example:
If you want to escape the apostrophe ' replace with \u0027
D'Amico becomes D\u0027Amico
NICE REFERENCE:
http://es5.github.io/x7.html#x7.8.4
https://mathiasbynens.be/notes/javascript-escapes
Using template literals...
var json = `{"1440167924916":{"id":1440167924916,"type":"text","content":"It's a test!"}}`;
Use encodeURIComponent() to encode the string.
Eg.:
var product_list = encodeURIComponent(JSON.stringify(product_list));
You don't need to decode it since the web server automatically do the same.
To allow single quotes within doubule quoted string for the purpose of json, you double the single quote. {"X": "What's the question"} ==> {"X": "What''s the question"}
https://codereview.stackexchange.com/questions/69266/json-conversion-to-single-quotes
The \' sequence is invalid.
regarding AlexB's post:
\' Apostrophe or single quote
\" Double quote
escaping single quotes is only valid in single quoted json strings
escaping double quotes is only valid in double quoted json strings
example:
'Bart\'s car' -> valid
'Bart says \"Hi\"' -> invalid