5

I have a string containing backslashes:

"{ \time 4/4 \key c \major d'4 }"

When I try to pass it in a nodejs child_process or just to console.log it, the backslashes are removed:

console.log("{ \time 4/4 \key c \major d'4 }");   
// "{   ime 4/4 key c major d'4 }"

I have tried all things I cound find, such as .replace(/\\/g, '\\') or JSON.stringify, but nothing seems to work.

The string is constructed dynamically so I can't escape it manually.

Any ideas?


Update after comments:

I am getting this string from a library written in python (python-mingus) using node-python.

As I understand from the answers and the comments, there is no way to parse the string correctly without altering either the library or the wrapper...

Thank you all.

mutil
  • 3,205
  • 1
  • 27
  • 34
  • 2
    `"{ \\time 4/4 \\key c \\major d'4 }"` works fine. You need to escape *before* you put your data into javascript. Where are you getting it from? – h2ooooooo May 26 '15 at 18:54
  • 2
    "constructed dynamically" how exactly, and why are the slashes there? If it's a string literal the slashes are probably being removed by the parser. – adeneo May 26 '15 at 18:54
  • The two-character string literal `\m` only expresses a one-character string value. JavaScript can only act on string values, not string literals. You might as well ask to preserve the `e` in the numeric literal `10e2`. You can't; that literal expresses the value `1000` and the value doesn't have an `e`. Similarly, the literal `\m` expresses the value `m` and the value doesn't have a backslash. – apsillers May 26 '15 at 18:56
  • 2
    You cannot fix the string if the literal is incorrect. The slashes are treated as escape sequences and are already discarded by the time it's a value in memory. You'll have to fix the "dynamic construction." – Jonathan Lonowski May 26 '15 at 18:58
  • Hopefully the backslashes are not important because they are gone by the time the javascript parser digests them. – KJ Price May 26 '15 at 19:00
  • JSON.stringify(str) will turn a string into a literal. perfectly. – dandavis May 26 '15 at 19:38
  • @dandavis, not perfectly, it keeps `\t` but strips the unrecognized sequences (`\k`, `\m`) – mutil May 26 '15 at 20:02
  • @mutil: JSON.stringify should turn "\k" into "\\k", unless you really fed it just "k". if that's the case, you need to feed it the source of your string, be it a file, callback, etc. once you have it parsed as a string, it's too late because the extra slash has been tossed. JSON.stringfiy will accept and return a string, so it can fit in the middle of whatever process provides your strings. – dandavis May 26 '15 at 20:06

3 Answers3

23

You could use String.raw as alternative to save strings containing slashes; To his you have to put your string between grave sign (`) as follows:

var path = String.raw`your\string\with\slash`;

this way you can preserve slashes.

Erique Bomfim
  • 409
  • 4
  • 7
  • Most ellegant solution, and actually really the intended behaviour of `String.raw`: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/raw : `"All kinds of escape characters will be ineffective and backslashes will be present in the output string"` – Max Nov 25 '22 at 11:26
  • Note that these strings can't have a trailing \. You may need to handle that specially. – Zach Saucier Dec 22 '22 at 17:57
4

No, your string does not contain (literal) backslashes.

\ is an escape character, and \t, \k and \m are treated as escape sequences at the time of parsing (and not at the time of printing, as you seem to think). They never even reach your replace because they aren't there anymore when it runs. Also, for unrecognised sequences (\k and \m), the backslash is simply ignored.

The only way to prevent that is to add an additional backslash in the source code:

"{ \\time 4/4 \\key c \\major d'4 }"
Siguza
  • 21,155
  • 6
  • 52
  • 89
0

Interestingly if you type the characters $$ \sum \theta $$ into an HTML text input box javascript will pick them up and pass them on unchanged and even console.log will print them out unchanged.

var TextSource = document.getElementById( "myHTMLTextInputBox" );
var labelStr = TextSource.value;
console.log ("Obtained text = ", labelStr);

Likewise you can type the same character sequence into the definition of an HTML DIV like this:-

<div id="anne" name="bob" class="carla" title ="tommy"> $$ \sum \theta $$ </div>    

(I wonder how those processes are explained in terms of parsing?)

steveOw
  • 879
  • 12
  • 41