Print string literally in javascript - javascript

I was trying to write a function convertStr with JavaScript that will print strings literally when used with console.log(convertStr(str)).
Some examples for input and output
str = '\'"\n\\'
console.log(convertStr(str))
> '\'"\n\\'
For doing this convertStr should convert '\'"\n\\' to '\'\\\'"\\n\\\\\''.
Let us consider a simpler example
str = '\''
convertStr(str) =====> '\'\\\'\''
console.log(convertStr(str)) =====> '\''
The first challenge here is to know whether we are enclosing str with ' or ". I don't think this is possible without making assumption.
Let's assume that str is enclosed using '.
The other challenge is there are lot of cases to handle.
After searching the web I tried few solutions
Attempt 1:
I tried JSON.stringify which breaks when I use escaped string quotes inside str
console.log(JSON.stringify('\"')) =====> "\""
console.log(JSON.stringify('\'')) =====> "'"
This solution fails for case with single quotes. This also fails when we use unicode escape
console.log(JSON.stringify('\u2260') ====> "≠"
Attempt 2:
I tried using str.replace(regex, replacestr) but could not find a solution that works for all cases like unicode or things like \x41 or \0.

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.

Issue with replacing hexadecimal escape sequences in a string in Javascript

I'm trying to fix a string which has some encoding characters in it.
I thought I should be able to match the hex characters of the special characters and convert them back to a normal character.
Here is my example code:
let str = "url('https\3a //');";
str = str.replace(/\x5C\x33\x61\x20/g,":"); // equivalent to '\3a '
console.log(str);
I expected the output to be url('https://'); but I actually got url('https a //');
What am I missing? jsfiddle here. Is this some sort of multi byte character issue? I looked at the resulting string in a hex editor and the replaced characters seem to be \x03\x61\x20 rather than the expected \x3A.
EDIT: why has this been down voted? It is a fair question isn't it?
Is the code that you use really needs to be in this form?
I got the desired result using "3a".
str = "url('https\3a //');";
str = str.replace(/\3a /g,":"); // equivalent to '\3a '
console.log(str);
//result: url('https://');

Split string into array but still keep it's comma when applying join. - Javascript

I'm having a hard time remembering how to split a string while still keeping the comma in the string and splitting special cases as well.
Example of what I'm trying to do is this:
> Input: "Welcome, <p>how<b>are you</p>do-ing</b>?"
> Output: ["Welcome,", " ", "<p>", "how", "<b>", "are you", "</b>", "</p>", "do-ing", "</b>", "?"]
What I have tried:
var str = "Welcome, <p>how<b>are you</p>doing</b>?",
arr = str.split(/([,\s])/);
Unfortunately the only way I can think about splitting the special cases is replace them with comma's before and after them, but all this does is cause problems trying to keep the original comma. I've been scratching my head at this and I know it's right in front of me. I have tried looking all over for examples or answers and I'm drawing a blank in what I'm trying to look for.
Use .match instead of .split:
var str = "Welcome, <p>how<b>are you</p>doing</b>?",
arr = str.match(/<[^>]+>|[^,<]+,?/g);
console.log(arr);
The pattern <[^>]+>|[^,<]+,? means:
Alternate between
<[^>]+> - Match < followed eventually by a >, or
[^,<]+,? - Match characters other than , and <, optionally followed by a ,

How do I properly escape and unescape a multiline string that contains newline literals?

I'm working on a Visual Studio Code extension. The extension is supposed to act on the text that is currently selected in the editor window and send it to an external command (lein-cljfmt in my case, but I think that's unrelated to my question). When the external command is done processing the text I want to replace the current editor selector with the result returned from the command line tool.
Before sending the string I escape it like this:
contents
.replace(/\\/g, '\\\\')
.replace(/"/g, '\\"')
.replace(/\n/g, '\\n');
The result in being unescaped like:
contents
.replace(/\\n/g, '\n')
.replace(/\\"/g, '"')
.replace(/\\\\/g, '\\');
This works in all but one case: when the selection that is being processed contains a string literal that contains a newline literal, the unescaping will instead turn this into a linebreak, thus breaking the code in the editor.
This is an example of a snippet that breaks my escaping:
(defn join
[a b]
(str a "\n" b))
I tried quite some regexp black magic like
.replace(/(?!\B"[^"]*)\\n(?![^"]*"\B)/g, '\n')
by now, but couldn't find a solution that does not have edge cases. Is there a way to do this that I am missing? I also wonder if there is a VSCode extension API that could handle that as it seems to be a common scenario to me.
I think this might be what you need:
function slashEscape(contents) {
return contents
.replace(/\\/g, '\\\\')
.replace(/"/g, '\\"')
.replace(/\n/g, '\\n');
}
var replacements = {'\\\\': '\\', '\\n': '\n', '\\"': '"'};
function slashUnescape(contents) {
return contents.replace(/\\(\\|n|")/g, function(replace) {
return replacements[replace];
});
}
var tests = [
'\\', '\\\\', '\n', '\\n', '\\\n', '\\\\n',
'\\\\\n', '\\\\\\n', '\\"\\\\n', '\n\n',
'\n\n\n', '\\n\n', '\n\\n', '\\n\\n',
'\\\n\\n\nn\n\\n\\\n\\\\n', '"', '\\"', '\\\\"'
];
tests.forEach(function(str) {
var out = slashUnescape(slashEscape(str));
// assert that what goes in is what comes out
console.log(str === out, '[' + str + ']', '[' + out + ']');
});
Trying to unescape the string in 3 stages is really tricky because \n has a different meaning depending on how many slashes there are just before it. In your example the original string of \n (slash n) gets encoded as \\n (slash slash n), then when you decode it the last two characters match the first of your RegExps when what you want is for the first two characters to match the third RegExp. You've got to count the slashes to be sure. Doing it all in one go dodges that problem by decoding those leading slashes at the same time.

Categories

Resources