-2

I am writing JScript to be run using Windows Script Host.

Say I have a simple string variable:

s1 = '\n'

I want to build s2 from two separated chars: \ & n. naively I would like to do:

s2 = '';
s2 += '\\';
s2 += 'n'; 

But this of course lead to s1 != s2

Can I build s2 in such way that it has the same interpreted meaning as s1?

Example:

WScript.Echo("1\n2")
var s;
s += '1';
s += '\\';
s += 'n';
s += '2';
WScript.Echo(s)

I'd wish both WScript.Echo() to print exactly the same thing.

Note

I'm well aware that this question seems completely idiotic. I would probably think the same had I read it without knowing all the details. I don't expect anyone to understand the purpose . just curious to see whether it is feasible or do I need to re-think the whole thing.

Community
  • 1
  • 1
idanshmu
  • 5,061
  • 6
  • 46
  • 92
  • 1
    Try `s2 = '\\n';`, though that still won't equal `s1`. – aroth Dec 14 '14 at 10:31
  • The whole challenge is that `s2` is build out of `s1` characters exactly as they are written in the source file (not the way they are being interpreted). I can't build `s2` in the way you suggested. – idanshmu Dec 14 '14 at 10:32
  • 1
    "Written in the source file"? As a string or a real new-line character? If the latter, notice, that Windows' new-line character is actually `\r\n`. That's exactly _two_ characters though, not four. – Teemu Dec 14 '14 at 10:59

4 Answers4

3

You can't build it directly by appending, but you can take a string with escape sequences in it and parse it to a string with the escaped characters. In this case, you'd probably use JSON.parse:

var s1 = '\n',
    s2 = '' + '\\' + 'n'; // '\\n'
console.log(s1 == JSON.parse('"' + s2 + '"')) // true
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • 1
    Still going to have to watch out for double quotes in the input string though – Dagg Nabbit Dec 14 '14 at 10:48
  • This is slightly insane. If we can do arbitrary things and just *assign s2 a completely new value*, why not simply do so explicitly? `if (s2 == '\\n') s2 = '\n';`? – user229044 Dec 14 '14 at 10:49
  • @DaggNabbit: Yeah, the string would need to be properly escaped like JSON. – Bergi Dec 14 '14 at 10:50
  • @meagar: We don't know where the single `\ ` and `n` characters are coming from. Of course, if they were hardcoded it would not make much sense – Bergi Dec 14 '14 at 10:51
2

You can't, this is impossible. You cannot concatenate two or more characters together to yield one character, which is what \n is. It is a string containing one single character.

user229044
  • 232,980
  • 40
  • 330
  • 338
  • agreed. However perhaps there is way to have special handling to escape. Like adding an if statement to identify escape before adding it to `s2`. Something like `if( c1 == '\\' && c2 == '\n') s2 += '\n'`. this is very ugly but it might work. – idanshmu Dec 14 '14 at 10:37
  • @idanshmu if you "don't expect anyone to understand the purpose" then don't expect a useful answer either. – Dagg Nabbit Dec 14 '14 at 10:38
  • @idanshmu Yes, **of course** that will work. That's obviously nothing like the code you've posted in your question. It simply appends a newline, it doesn't "build" new line out of other characters. Did you try it before asking? – user229044 Dec 14 '14 at 10:42
  • @DaggNabbit I understand. But in some cases you don't need to be aware of everything in order to post a useful answer. I'm trying to post questions in the most concise way that I can. in most cases it works. In other cases I look stupid. – idanshmu Dec 14 '14 at 10:42
  • 3
    @idanshmu it smells like an [XY problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) to me. – Dagg Nabbit Dec 14 '14 at 10:43
  • @meagar I don't want to handle these corner cases manually while building `s2`. I thought there might be more elegant way, that I'm not aware of, to solve this. – idanshmu Dec 14 '14 at 10:44
  • 3
    @idanshmu You haven't told us *anything* about your problem, or why this is a corner case, or what other kinds of cases you might encounter. If you actually tell us what your problem is, instead of wasting everybody's time, you might get the "elegant way" you're after. Nobody is going to give you an elegant solution for a problem you're refusing to tell us. – user229044 Dec 14 '14 at 10:46
0

It's still somewhat unclear to me what you're actually trying to accomplish. However, if you're saying that you have some arbitrary string like var s1 = '\n\r\t';, and you want to produce from that the literal string "\n\r\t" so that when you parse the literal value you get a result that is equivalent to your original string, perhaps you can try something like this:

window.specialChars = {
    8: "\\b",       //backspace
    9: "\\t",       //tab
    10: "\\n",      //newline
    12: "\\f",      //form-feed
    13: "\\r",      //carriage return
    39: "\\'",      //single-quote
    92: "\\\\"      //literal backslash  
};

function escapedString(source) {
    if (! source) {
        return undefined;
    }

    var result = "";
    for (var index = 0; index < source.length; index++) {
        var code = source.charCodeAt(index);
        result += specialChars[code] ? specialChars[code] : String.fromCharCode(code);
    }

    return result;
};

http://jsfiddle.net/L4L16xwu/3/

Of course there are a number of problems you may run into here. Particularly if your source string may contain non-ASCII characters or spurious escape sequences (for instance, var s1 = '\q'; is valid JavaScript and will store a value of "q" in s1, and when processing that there's no way to tell that the original source string has a spurious \ in it).

It may be that there's a better alternative to solving whatever underlying problem you're attempting to solve with this "unparse the string" approach.

aroth
  • 54,026
  • 20
  • 135
  • 176
0

I actually have the need to do this today. In particular, I need it for building up octal and hexadecimal escape sequences of the form \x39 or \123.

The method I'm using is simply to use an eval:

var str = eval('"\\x' + '3' + '9' +'"') // str === "9"

That's a reasonable generic solution. For octal and hex codes, it would be better to parse the string into an int and then build a string from that

var str = String.fromCharCode(parseInt('39', 16))
Dancrumb
  • 26,597
  • 10
  • 74
  • 130