1

I have a list of special characters: + - & | ! ( ) { } [ ] ^ ~ * ? \ :

I want to escape all of them with a leading \\ except of \ that needs only ohne leading backslash \ e.g. a string that is (1+1)\2 must be changed to \\(1\\+1\\)\\2 In fact it prepends two backslashes to each defined special character, and only one backslash to a backslash.

I wrote this function, that works actually quite good:

function escapeSpecialCharacters(input) {
  var output = input.replace(/\+/g, "\\\+")
    .replace(/\-/g, "\\\-")
    .replace(/\&/g, "\\\&")
    .replace(/\|/g, "\\\|")
    .replace(/\!/g, "\\\!")
    .replace(/\(/g, "\\\(")
    .replace(/\)/g, "\\\)")
    .replace(/\{/g, "\\\{")
    .replace(/\}/g, "\\\}")
    .replace(/\[/g, "\\\[")
    .replace(/\]/g, "\\\]")
    .replace(/\^/g, "\\\^")
    .replace(/\~/g, "\\\~")
    .replace(/\*/g, "\\\*")
    .replace(/\?/g, "\\\?")
    .replace(/\:/g, "\\\:")
    .replace(/\\/g, "\\\\");

  return output;
}
console.log(escapeSpecialCharacters("(1+1)\\2"));

But im not happy with the current implementation. Because i think its quite hard to read an to maintain.

Is there any other "smarter" solution/framework available for this problem? I was thinking of a function that uses a given list of special characters to replace them in my string.

DieGraueEminenz
  • 830
  • 2
  • 8
  • 18

2 Answers2

2

Did see this regex:

/([-\/\\^$*+?.()|[\]{}])/g

here? Using String.raw on a template literal of input so octal can be interpreted as a literal \2. \ being exception (for some unfathomable reason) you can chain .replace().

const escape = string => string.replace(/([-\/^$*+?.()|[\]{}])/g, `\\$1`).replace(/([\\])/g, `\\\$1`);

console.log(escape(String.raw`(1+1)\2`));
zer00ne
  • 41,936
  • 6
  • 41
  • 68
  • your snippet delivers \\\2 for \2, but i expect \\2 in this case – DieGraueEminenz Jun 04 '19 at 11:33
  • looks great! Still hard to read, but less error-prone than my implementation. Thank you! – DieGraueEminenz Jun 04 '19 at 11:53
  • 1
    @DieGraueEminenz Indeed, arrow functions are hard for me to read as well, but I persist in using them so they'll eventually become second nature. You're very welcome, don't forget to check the checkmark ✅ if this answer resolved your issue. – zer00ne Jun 04 '19 at 12:19
0

You can check this solution. I've just loop through all the characters one by one and checking which one is matching and then just append forward slashes as prefix.

const specialChars  = ["+", "-" ,"&", "|", "!", "(", ")", "{", "}", "[", "]", "^", "~", "*", "?", "\\", ":",];
let string = `(1+1)\\2`; // double slash is needed to avaoid escaping

let changedString = string.split('').reduce((newString, char) => {
  if(specialChars.includes(char) && char !== '\\') {
    return newString += `\\\\${char}`;
  } else if(char == "\\") {
      return newString += `\\${char}`;
  } else {
      return newString += char;
  }
}, '')

console.log(changedString)
Sifat Haque
  • 5,357
  • 1
  • 16
  • 23