2

I have a string that may contain double quotes in it. I know I can escape the string by replacing " with \" like:

myString.value.replace(/\"/g, "\\\"");

But doing this can create another issue where if some double quotes are already escaped. For instance if I already have \" in my string, running this will change that to \" which is something I do not want.

Is there a way to ignore already escaped double quotes and only replace the ones that are not ?

Tohid
  • 21,535
  • 8
  • 30
  • 43
  • 4
    And if you have `\\"`, does the first ``\`` escape the second one, so `"` is not escaped, and thus should be replaced? – Oriol Oct 07 '15 at 18:13
  • maybe duplicate of: [replace-a-pattern-in-string-only-if-a-certain-condition-is-satisfied-regex](http://stackoverflow.com/questions/16339771/replace-a-pattern-in-string-only-if-a-certain-condition-is-satisfied-regex) – Ziki Oct 07 '15 at 18:23
  • Do not use regexes to parse potentially escapable quotes. It's a context-free problem that should be solved with a simple context-free parser. See http://stackoverflow.com/questions/632475/regex-to-pick-commas-outside-of-quotes/29461162#29461162 – Touffy Oct 07 '15 at 18:31

3 Answers3

2

You can use replace with a callback for this:

var s = s = 'abc "def" \\"foo bar\\" 123';
var r = s.replace(/(\\*)"/g, function($0, $1) {return ($1.length % 2) ? $0 : '\\' + $0; });
//=> abc \"def\" \"foo bar\" 123

More Testing:

> 'ab"c'.replace(/(\\*)"/g, function($0, $1) {return ($1.length % 2) ? $0 : '\\' + $0;}); 
"ab\"c"

> 'ab\\"c'.replace(/(\\*)"/g, function($0, $1) {return ($1.length % 2) ? $0 : '\\' + $0;}); 
"ab\"c"

> 'ab\\\\"c'.replace(/(\\*)"/g, function($0, $1) {return ($1.length % 2) ? $0 : '\\' + $0;}); 
"ab\\\"c"

> 'ab\\\\\\"c'.replace(/(\\*)"/g, function($0, $1) {return ($1.length % 2) ? $0 : '\\' + $0;}); 
"ab\\\"c"

> 'ab\\\\\\\\"c'.replace(/(\\*)"/g, function($0, $1) {return ($1.length % 2) ? $0 : '\\' + $0;}); 
"ab\\\\\"c"
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • You're not counting the backslashes so, on odd numbers of backslashes, you'll end up escaping the backslash and leaving the quote unescaped. – Touffy Oct 07 '15 at 19:13
  • Please provide example input – anubhava Oct 07 '15 at 19:15
  • Just a simple modification of your example: `'abc "def" \\"foo bar\" 123'` – Touffy Oct 07 '15 at 19:16
  • With your original example you're replacing all `\"` with `\\"`, the correct escaping would be `\\\"` (or just `\"` if you don't care about the backslash). You can see in my modified example that your code is doing the same thing in the case of a single backslash. – Touffy Oct 07 '15 at 19:18
  • 1
    ok now I understand. No way I intended to solve the cases of multiple backslashes originally. Anyway after your comment I reworked the regex and provided many examples. – anubhava Oct 07 '15 at 20:17
0

As it happens, the problem of escaping quotes in strings has a built-in solution so you don't need to implement a parser yourself. Just use JSON.stringify :)

What you'll get is your string, wth properly escaped quotes and backslashes, with double quotes around it that you may or may not want to trim.

JSON.stringify("\\\"")
=> "\"\\\"\""
Touffy
  • 6,309
  • 22
  • 28
-1

So escape only unescaped quotes:

myString.value.replace(/[^\\]\"/g, "\\\"");
Oeeq
  • 7
  • 2