I am creating an JSON file which stores some Physics equation, which will be rendered using MathJax.
"equations": [
"$w = F.s\cos\theta$"
]
I am getting a bad string error. I have tried adding another backslash before the slashes but that changes the equations drastically.
Is there any way to fix this issue without changing the equation
There were two issues you were falling over.
Firstly, a valid JSON file will have { and } around it (as David Gatti mentions in his answer, it is an object after all). Secondly, certain characters - including backslashes - will need to be escaped. When you parse it back into an object, the additional backslashes will be removed.
Your corrected JSON should read:
{
"equations": [
"$w = F.s\\cos\\theta$ "
]
}
JSON is an encoding of structured data. You write
{
"equations": [
"$w = F.s\\cos\\theta$"
]
}
to mean an object with a property named equations with an array with a single string:
$w = F.s\cos\theta$
The escaped backslashes (\) does not change the underlying data. They get removed by the receiver when the JSON gets decoded into the object graph.
Related
In Javascript, I need to "fix" a string, supposed to be JSON valid but may not be. The string has the following format (the unknown part is marked with "<INVALID_CHARS>"):
[
{ "key_1": "ok_data", "key_2": "something_valid <INVALID_CHARS>"},
{ "key_1": "ok_data", "key_2": "some_valid_value"}
]
"INVALID_CHARS" are chars which make the JSON.parse() function fail.
The errors are always localized on the "key_2" property of this array elements.
Note that these chars come from random binary data, and can thus be anything.
I would like to find the simplest solution, or at least one which is the least prone to errors.
I thought of replacing invalid characters, but there is also a problem with single backslash chars followed by a non special char, throwing an error too, or quote chars.
And I probably did not think of all the possible errors.
Thank you.
JSON is not allowed to contain arbitrary binary data; it must be a sequence of valid Unicode codepoints. (Usually these are transmitted in UTF-8 encoding, but regardless, arbitrary binary data is not possible.) So if you want to include arbitrary binary data you'll need to figure out how to unambiguously encode it for transmission. If you don't encode it in some way, then you won't be able to reliably distinguish a byte which happens to have the same code as " from the " which terminates the string.
There are a number of possible encodings you might use for which standard libraries exist in most languages. One of the most commonly used is base-64.
it's better to clarify the problem as seems you described wide range of the issues here. If you have problem with parsing structure above you just need to check the syntactic integrity of the structure. For example this structure parses well
let var1 = JSON.parse('[
{
"key_1":"ok_data",
"key_2":"something_valid <INVALID_CHARS>"
},
{
"key_1":"ok_data",
"key_2":"some_valid_value"
}
]');
In case if you need to replace <INVALID_CHARS> as binary data with json characters it's possible to encode <INVALID_CHARS> in base64 as it's the most reliable way. But I guess also problem not only to pack <INVALID_CHARS> to base64 and problem is also architectural and you need to prepare value of key_2 with valid part and invalid part. In this way, I would suggest separate (split) key_2 on two substrings separate by " " - "key_2": "something_valid <INVALID_CHARS>(can be omitted)".
Moreover, it's possible to use separate fields for string without error and a second for errors. Like this "key_2_1": "something_valid", "key_2_2":<INVALID_CHARS>
Another way is to look to using Multipart Form Data if it's possible, to transfer binary data
I am converting a csv file into JSON, and the converter adds " at the beginning of lines, and also adds a \ to quotes.
So, if my CSV file has an array like
"items": [{"name":"item 1"...
the resulting JSON from the converter is:
"items": "[{\"name\":\"item 1\"...
I need the JSON to look like the original CSV entry.
So, how do I change "[{ to [{ ?
Note: I can't just remove quotes everywhere, as they are correct in certain spots. So I need to just remove quotes when they are followed by these specific characters, so only remove "[{
And how do I remove the \ everywhere they appear?
EDIT
Some of the comments and answers have mentioned maybe there is a better way to convert the CSV into a JSON file. In my case, I have data in excel that I need to ultimately be readable by a Lambda function, so I expect I need a way to convert excel to JSON. I have posted a separate question asking for assistance on that topic here .
First of all you should try to generate the correct json format, so that you don't have to go through this issue at all.
However if you have no control over the output of the json data that you're getting, you can simply remove the \" parts by using this regexp:
your_json_var.toString().replace(/\"/g,'');
Where your_json_var contains the returned data.
your_json_var = '"items": "[{\"name\":\"item 1\"...';
var new_var = your_json_var.toString().replace(/\"/g,'');
console.log(new_var);
You could do this
Let stringJson=JSON.stringify(myjson)
Let clearJson = JSON.parse(stringJson.replace(/\"[{/g, '[{').replace(/\/g,'')
I am facing some issues with escaping of back slash, below is the code snippet I have tried. Issues is how to assign a variable with escaped slash to another variable.
var s = 'domain\\username';
var options = {
user : ''
};
options.user = s;
console.log(s); // Output : domain\username - CORRECT
console.log(options); // Output : { user: 'domain\\username' } - WRONG
Why when I am printing options object both slashes are coming?
I had feeling that I am doing something really/badly wrong here, which may be basics.
Update:
When I am using this object options the value is passing as it is (with double slashes), and I am using this with my SOAP services, and getting 401 error due to invalid user property value.
But when I tried the same with PHP code using same user value its giving proper response, in PHP also we are escaping the value with two slashes.
When you console.log() an object, it is first converted to string using util.inspect(). util.inspect() formats string property values as literals (much like if you were to JSON.stringify(s)) to more easily/accurately display strings (that may contain control characters such as \n). In doing so, it has to escape certain characters in strings so that they are valid Javascript strings, which is why you see the backslash escaped as it is in your code.
The output is correct.
When you set the variable, the escaped backslash is interpreted into a single codepoint.
However, options is an object which, when logged, appears as a JSON blob. The backslash is re-escaped at this point, as this is the only way the backslash can appear validly as a string value within the JSON output.
If you re-read the JSON output from console.log(options) into javascript (using JSON.parse() or similar) and then output the user key, only one backslash will show.
(Following question edit:)
It is possible that for your data to be accepted by the SOAP consuming service, the data needs to be explicitly escaped in-band. In this case, you will need to double-escape it when assigning the value:
var s = 'domain\\\\user'
To definitively determine whether you need to do this or not, I'd suggest you put a proxy between your working PHP app and the SOAP app, and inspect the traffic.
I am using Dojo.fromJson to convert json string to javascript object, but throw exception. Because, there are control characters such as ',\n,\r in the json string.
How can I solve this problem in dojo? convert json string to javascript object, even if there are control characters.
I use Newtonsoft.JsonConvert.SerializeObject to convert C# oject to json data. Json Object: {"name":"'\"abc\n123\r"} then, I use Dojo.fromJson(' {"name":"'\"abc\n123\r"}') to convert json data to javascript object.
Thank you very much!
Problem, i believe is the double-quote which should be escaped by triple backslashes. You can use "native browser JSON decode" as searchterm for "dojo fromJson" synonym.
Without knowing my way around C# - I havent tested but i believe following should work:
string c_sharp_name = "'\"abc\n123\r";
// C#Object.name
c_sharp_name = c_sharp_name.
replace('"', '\\"'). // maybe add a slash on serverside
replace('\n', '\\\n').
replace('\r', '\\\r');
since
while this fails:
{"name":"'\"abc\n123\r"} // your single backslash
this would work:
{"name":"'\\\"abc\\\n123\\\r"} // working triple backslash escape
I am using jQuery's getJSON function to make a request and handle the JSON response. The problem is the response I get back is malformed and I can't change it. The response looks something like this:
{
aNumber: 200,
someText: '\'hello\' world',
anObject: {
'foo': 'fooValue',
'bar': '10.0'
}
}
To be valid JSON, it should look like this:
{
"aNumber": 200,
"someText": "'hello' world",
"anObject": {
"foo": "fooValue",
"bar": "10.0"
}
}
I would like to change the text returned to a valid JSON object. I've used the JavaScript replace function to turn the single quotes into double quotes and the escaped single quotes into single quotes, but now I am stuck on figuring out the best way to add quotes around the key values.
For example, how would I change foo: "fooValue" to "foo":"fooValue"? Is there a Regular Expression that can make this easy?
Thanks in advance!
This regex will do the trick
$json = preg_replace('/([{,])(\s*)([A-Za-z0-9_\-]+?)\s*:/','$1"$3":',$json);
It's a php though! I assume it's not a problem converting it to JS.
I was trying to solve the same problem using a regEx in Javascript. I have an app written for Node.js to parse incoming JSON, but wanted a "relaxed" version of the parser (see following comments), since it is inconvenient to put quotes around every key (name). Here is my solution:
var objKeysRegex = /({|,)(?:\s*)(?:')?([A-Za-z_$\.][A-Za-z0-9_ \-\.$]*)(?:')?(?:\s*):/g;// look for object names
var newQuotedKeysString = originalString.replace(objKeysRegex, "$1\"$2\":");// all object names should be double quoted
var newObject = JSON.parse(newQuotedKeysString);
Here's a breakdown of the regEx:
({|,) looks for the beginning of the object, a { for flat objects or , for embedded objects.
(?:\s*) finds but does not remember white space
(?:')? finds but does not remember a single quote (to be replaced by a double quote later). There will be either zero or one of these.
([A-Za-z_$\.][A-Za-z0-9_ \-\.$]*) is the name (or key). Starts with any letter, underscore, $, or dot, followed by zero or more alpha-numeric characters or underscores or dashes or dots or $.
the last character : is what delimits the name of the object from the value.
Now we can use replace() with some dressing to get our newly quoted keys:
originalString.replace(objKeysRegex, "$1\"$2\":")
where the $1 is either { or , depending on whether the object was embedded in another object. \" adds a double quote. $2 is the name. \" another double quote. and finally : finishes it off.
Test it out with
{keyOne: "value1", $keyTwo: "value 2", key-3:{key4:18.34}}
output:
{"keyOne": "value1","$keyTwo": "value 2","key-3":{"key4":18.34}}
Some comments:
I have not tested this method for speed, but from what I gather by reading some of these entries is that using a regex is faster than eval()
For my application, I'm limiting the characters that names are allowed to have with ([A-Za-z_$\.][A-Za-z0-9_ \-\.$]*) for my 'relaxed' version JSON parser. If you wanted to allow more characters in names (you can do that and still have valid JSON), you could instead use ([^'":]+) to mean anything other than double or single quotes or a colon. This would still limit you further than the JSON standard (which allows single quotes in the name) but then you wouldn't be able to parse using this method. You can have all sorts of stuff in here with this expression ([^'":]+), so be careful.
Hope this helps.
edit — came back to point out, first and foremost, that this is not a problem that can be solved with a regular expression.
It's important to distinguish between JSON notation as a serialized form, and JavaScript object constant notation.
This:
{ x: "hello" }
is a perfectly valid JavaScript value (an expression fragment), so that this:
var y = { x: "hello" };
gives you exactly the same result as:
var y = { "x": "hello" };
In other words, the value of "y" in either of those cases will be exactly the same. Completely, exactly the same, such that it would not be possible to ever tell which of those two constants was used to initialize "y".
Now, if what you want to do is translate a string containing JavaScript style "JSON shorthand" without quotes into valid JSON, the only thing to do is parse it and reconstruct the string with quotes around the property names. That is, you will have to either write your own "relaxed" JSON parser than can cope with unquoted identifiers as property names, or else find an off-the-shelf parser that can handle such relaxed syntax.
In your case, it looks like once you have the "relaxed" parser available, you're done; there shouldn't be any need for you to translate back. Thankfully, your "invalid" JSON response is completely interpretable by JavaScript itself, so if you trust the data source (and that's a big "if") you should be able to evaluate it with "eval()".
UPD 2020: the object you have is a valid javascript object, but not 100% valid JSON.
An easy way to convert it to valid JSON is to utilize the features JavaScript provides you with, JSON.stringify:
JSON.stringify(object)
You can run this in your browser's JS console.
To get it formatted (aka "pretty-printed"), you can pass two arguments to this function - the replacer (a function which allows you to filter out some of the properties of your object; just pass a null if you don't care) and space (either the number of spaces or a string which will be placed before each key-value pair of your object' string representation):
JSON.stringify(object, null, 4)
In your case, this call
JSON.stringify({
aNumber: 200,
someText: '\'hello\' world',
anObject: {
'foo': 'fooValue',
'bar': '10.0'
}
}, null, 4)
will give you
{
"aNumber": 200,
"someText": "'hello' world",
"anObject": {
"foo": "fooValue",
"bar": "10.0"
}
}
You **do not** need to do this - you've already got a valid **JSON object**. Read 'bout JSON [here][1].
If you need to get value, you just write `data.whatever` and it just works. E.g.: if you have JSON **object** `data`:
{
moo: "foo",
foo: "bar"
}
All possible fields are `moo` and `foo` and their use are `data.moo` and `data.foo` respectively. And if you want to use `data` as a jQuery argument, you just pass it as-is: `$.load("http://my.site.com/moo", data, function(response){ /* ... */ })`.
**Note:** in the last example i've mentioned, response will be a string. To make it a valid JSON object use `$.parseJSON(response);` method.
Since it's a malformed "JSON", you will not be able to use jQuery.getJSON.
You can use
jQuery.ajax({
url : myUrl,
data : myParams,
type : "GET",
success : function(jsontext)
{
// jsontext is in text format
jsontext = jsontext.replace("'", "\"");
// now convert text to JSON object
var jsonData = eval('(' + jsontext+ ')');
// rest of the code
}
});