1

I am writing a function that will remove a \\ and replace it with a \. I notice that the code also does not work for backslashes that aren't powers of two (other than two, of course).

function x(input){
  var arr = [];
  for(var i = 0; i < input.length; i++){
    var result = input[i].replace(/\\\\/g, '\\');
    arr.push(result);
  }

  return arr;
}

console.log(x(['\\a']));

The code will return [ '\\a' ].

EDIT:

Here is a more complicated example:

Input : ["\\\\\\"\\"a\\""] Output : [ '\\""a"' ] Desired output: ["\\\"\"a\""]

8
  • Are you pointing out x(['\\a']) because it's a result you do not expect? If so, what do you expect it to return? '\\a' becomes a string literal representing \a (because it is in a string, the first backslash escapes the second, making it a literal backslash). \a does not match \\ (which is what your regex is searching for), so nothing is replaced and \a is pushed as-is to the arr array that is returned. Commented Jun 25, 2017 at 22:28
  • I realize that the replace uses a string literal, and that is why this code does not work as intended, but I cannot think of any way to accomplish what I want - which is for the console to log ['\a']. Ultimately I am building a JSON parser, and it needs to be able to support escape characters. Commented Jun 25, 2017 at 22:35
  • You should provide more example of desired input and output. Commented Jun 25, 2017 at 22:39
  • "\\\\\\"\\"a\\"" is not a valid string... I think you are missing some basics about js strings. Commented Jun 25, 2017 at 22:49
  • The way it is passed into the parser is '["\\\\\\"\\"a\\""]' so it is a valid string. It also becomes a valid string in its own right if it gets parsed correctly. Commented Jun 25, 2017 at 23:45

2 Answers 2

3

When using regex,

  • a literal reverse solidus (a.k.a. backslash,( a.k.a. \)) must be escaped with a \ .

  • So when you input \\, that's literally \.

  • If you want to input 2 \ each one must be escaped. That means \\\\ is literally a string of 2 \.

The following demo uses ES6 Template Literals:

  • It's a new syntax for String that uses the backtick ` (top left corner key) instead of quotes " or '.

  • It can interpolate variables by prefixing with ${ and suffixing with }.

    var x = 2; `this template literal will display x as ${x}.`
    // this template literal will display x as 2.
    
  • The \ is U+5c in unicode. Using escaped unicode in Template Literal, it would be prefixed with \u{ and suffixed with }

    `A template literal with an escaped unicode backslash is \u{5c}`
    // A template literal with an escaped unicode backslash is \.
    

Demo

function XtoY(str, x, y) {
  var rgx = `/${x}/g`;
  var result = str.replace(rgx, `${y}`);
  return result;
}

const uni = `\u{5c}`;
const string = `\\a\\a\\b`;
const from = `${uni}${uni}`
const to = `${uni}`;

let z = XtoY(string, from, to);

console.log(z);

Sign up to request clarification or add additional context in comments.

2 Comments

That's interesting that there is a way to do this in es6, but it does not seem possible on earlier versions. Also, in my posted code I used '\\\\' to denote two backslashes.
'\\\\' is the correct way to denote 2 backslashes. You already have a grasp of escaped special characters, sorry I thought that was your question. If you wanted a way to input \\a and literally interpret each backslash as it was given, ex. input: \\a interpreted as: \\a then Template Literal String.raw is perfect solution. You can breakdown strings that have hundreds of backslashes. A simple substitution function can provide a raw string and a normal string literal ("cooked") version as a result.
0

When we pass in "["\\\\\\"\\"a\\""]" into with console.log(), the string that the function actually sees looks like "["\\\"\"a\""]" because the input string is being escaped before being passed to the function. The replace regex looks for double backslashes, so given the input, it will only match the first two backslashes of that group of three, replacing it with one, and leaving the rest as is... which is why it will return "["\\"\"a\""]".

If you call the function, getting the input string from an input field, for instance, your function works as desired.

If you WANT to achieve your desired result using explicit string literals, you can use /\\/g as the replace regex (effectively just not doing the replace at all), but it will not work both ways unless, as far as I know, you provide the function a way of knowing where the string came from (perhaps with an optional parameter) and manually handling the possibilities.

For example:

function x(input, caller) {
  return input.replace(caller === 'console' ? /\\/g : /\\\\/g, "\\");
}

console.log(x('["\\\\\\\"\\"a\\""]', "console"));

$("button").click(function() {
  console.log(x($("input").val()));
});

That checks if the call to the x function was passed a 2nd parameter with the value of "console" and changes the regex for the replace function accordingly.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.