Bug with Javascript's JSON.parse? - javascript

console.log(JSON.parse('{"data":"{\"json\":\"rocks\"}"}'));
gives error (tested on Firefox and Chrome's console). Is this a bug with JSON.parse? Same decodes well when tested with PHP.
print_r(json_decode('{"data":"{\"json\":\"rocks\"}"}', true));

This string is processed differently in PHP and JS, i.e. you get different results.
The only escapes sequences in single quoted strings in PHP are \\ and \'. All others are outputted literally, according to the documentation:
To specify a literal single quote, escape it with a backslash (\). To specify a literal backslash, double it (\\). All other instances of backslash will be treated as a literal backslash: this means that the other escape sequences you might be used to, such as \r or \n, will be output literally as specified rather than having any special meaning.
In JS on the other hand, if a string contains an invalid escape sequence, the backslash is discarded (CV means character value):
The CV of CharacterEscapeSequence :: NonEscapeCharacter is the CV of the NonEscapeCharacter.
The CV of NonEscapeCharacter :: SourceCharacter but not EscapeCharacter or LineTerminator is the SourceCharacter character itself.
The quote might not be helpful by itself, but if you follow the link and have a look at the grammar, it should become clear.
So in PHP the string will literally contain \" while in JS it will only contains ", which makes it invalid JSON:
{"data":"{"json":"rocks"}"}
If you want to create a literal backslash in JS, you have to escape it:
'{"data":"{\\"json\\":\\"rocks\\"}"}'

To have a literal backslash in a string literal,you need \\.
console.log(JSON.parse('{"data":"{\\"json\\":\\"rocks\\"}"}'));
This will successfully escape the inner quotation marks for the JSON processing.

You need to escape the backslashes:
console.log(JSON.parse('{"data":"{\\"json\\":\\"rocks\\"}"}'));​

object with one or more then '\' wont return Object by JSON.parser, It will return the string again with skipping one '\'.
You can do parse again and again until all '\' skipped.
myobj = {\"json\":\"rocks\"}
myobj = {\\"json\\":\\"rocks\\"}
Following lines worked for me
remove backslash
while(typeof myobj == 'string'){
myobj = JSON.parse(myobj)
}

You don't really need to escape double quotes inside single quotes and you have two extra quotes in your input around inner object, just
console.log(JSON.parse('{"data":{"json":"rocks"}}'));
is enough.

Related

When is the HTML attribute backslash escaped as a JavaScript string?

I noticed that backslash is escaped when I get "attribute value including backslash" with JavaScript in the following code.
console.log(document.getElementById("test").getAttribute("class")); // -> \A
console.log(document.getElementById("test").getAttribute("class").replace("\\A", "\A")); // -> A
console.log(document.getElementById("test").dataset.b); // -> \B
console.log(document.getElementById("test").dataset.b.replace("\\B", "\B")); // -> B
<div id="test" class="\A" data-b="\B"></div>
The backslash is treated as a special character in JavaScript, and two backslashes (\\) represent one backslash (\).
The result of the above code means that when getting the attribute value with JavaScript using getAttribute(), one backslash (\) is escaped to two backslashes (\\) at somewhere.
However, in the specification, it seems that the corresponding process is not applied.
Question
In which process of getAttributes() the backslash of HTML attribute is escaped (\ -> \\)?
There's a difference between string literals (which require escaping) and string values from other places (like html, ajax, etc), which are what they look like. Only when converted to literals (ex: JSON.stringify, some console views, etc) do JS strings have backslash escaping. The escape is an output formatting artifact; internally, there are no escapes in the sequence of characters.
HTML doesn't need the same escaping on blackslashes, due to different roots of the standard. An attribute isn't "converted" to one with escaped backslashes unless it's formatted as a string literal. That would happen at a stage between the string and it's visible output. You can use alert() instead of console.log() to see the string as it really is. I believe that specifically for the console, the
goal is to be more helpful to developers than accurate to the internals.

Split on backslash merges split elements

I try to split a string on a backslash. However, the split method doesn't return 2 elements but just 1 without the backslash:
'0.023750\0.023746'.split("\\")
> ["0.023750.023746"]
split method doesn't work, because "\0" is special symbol as "\n" or "\r" that means NULL. So that why your string is interpreted incorrectly. Solution is: write before your string symbol 'r'. It will say to interpreter to ignore special symbols.
r'0.023750\0.023746'.split("\\")
> ['0.023750', '0.023746']

String.replace() in case of different encodings

When I use JSON.stringfy().replace(/[\t\r\n]/g,"").trim() on response messages (lambda functions callbacks) from different system I face an issue where \t will be replaced with \\t and \ to \\\
Is there a way to avoid this?
I tried to search for answers but only found articles for base cases.
JSON.stringify's specific purpose is to convert what you give it to JSON. If what you give it is a string with backslashes in it, then what you'll get back is the JSON representation of that string, which is the string encased in double quotes (") with any special characters, such as backslashes, escaped with a backslash, newlines converted to \n, carriage returns converted to \r, etc.
Example:
const str = document.querySelector("input").value;
console.log("The string:", str);
console.log("JSON.stringify's output:", JSON.stringify(str));
<input type="text" value="This string has a backslash in it: \ For instance, here's a backslash followed by a t: \t">
That's what JSON.stringify does. If you don't want that, don't use JSON.stringify.
...in case of different encodings
That part is irrelevant. By the time you're dealing with a JavaScript string, it doesn't matter what encoding was used to represent that string (in an HTML file, a .js file, etc.). Once it's in memory, it's in the one format for JavaScript strings defined by the language (which is essentially UTF-16, except invalid surrogate pairs are allowed).

Getting an error with Console.log('\x') in JavaScript

the problem occurs only when the word after the '\' begin with 'x'. I would like to know if \x is reserved word.
It is not a reserved word, it's a way to print a character by its code:
>>> console.log('\x56');
V
In fact, Firebug tells you what's wrong if you omit the number:
SyntaxError: malformed hexadecimal character escape sequence
Like in many C-style languages, backslashes denote "escape sequences". More can be found here.
Backslash is used to escape characters. If you need a literal backslash, use \\.

javascript: some problem with compiler interpreting // as comments in regex

I've got this regular expression for validating phone numbers
^(\+?|(\(\+?[0-9]{1,3}\))|)([ 0-9.//-]|\([ 0-9.//-]+\))+((x|X|((e|E)(x|X)(t|T)))([ 0-9.//-]|\([ 0-9.//-]+\)))?$
I dugged it out from my C#/vb library and now i want to translate it into javascript. But it has syntax error (i suspect it is something due to the // characters). my attempt:
$IsPhone = function (input) {
var regex = new window.RegExp("^$|^(\+?|(\(\+?[0-9]{1,3}\))|)([ 0-9.//-]|\([ 0-9.//-]+\))+((x|X|((e|E)(x|X)(t|T)))([ 0-9.//-]|\([ 0-9.//-]+\)))?$", "");
return regex.test(input.trim());
};
alert($IsPhone("asd"));
Your problem has nothing to do with comments. You're just mixing up the two different ways of creating RegExp objects.
When you create a RegExp object in JavaScript code, you either write it as a string literal which you pass to a RegExp constructor, or as a regex literal. Because string literals support backslash-escape sequences like \n and \", any actual backslash in the string has to be escaped, too. So, whenever you need to escape a regex metacharacter like ( or +, you have to use two backslashes, like so:
var r0 = "^$|^(\\+?|(\\(\\+?[0-9]{1,3}\\))|)([ 0-9./-]|\\([ 0-9./-]+\\))+((x|X|((e|E)(x|X)(t|T)))([ 0-9./-]|\\([ 0-9./-]+\\)))?$";
var regex0 = new RegExp(r0, "");
The forward-slash has no special meaning, either to regexes or strings. The only reason you ever have to escape forward-slashes is because they're used as the delimiter for regex literals. You use backslashes to escape the forward-slashes just like you do with regex metacharacters like \( or \+, or the backslash itself: \\. Here's the regex-literal version of your regex:
var regex1 = /^$|^(\+?|(\(\+?[0-9]{1,3}\))|)([ 0-9.\/-]|\([ 0-9.\/-]+\))+((x|X|((e|E)(x|X)(t|T)))([ 0-9.\/-]|\([ 0-9.\/-]+\)))?$/;
from Errors translating regex from .NET to javascript
The backslash character in JavaScript
strings is an escape character, so the
backslashes you have in your string
are escaping the next character for
the string, not for the regular
expression. So right near the
beginning, in your "^(+?, the
backslash there just escapes the + for
the string (which it doesn't need),
and what the regexp sees is just a raw
+ with nothing to repeat. Hence the error.

Categories

Resources