1

I am trying to split a string based on the delimter \$. I have tried this unsuccessfully.

The code that I have is at https://js.do/sun21170/77657, which is also pasted below.

Question: What am I doing wrong in this example when splitting by \$?

var trickyString = "sd sewq wee r r ttttt $300 rrtrt utu iwiwi \$500 kjgf ihj \$215 ghi"; 

//document.getElementById("div0").innerHTML = trickyString;

function splitString() {
    //Why is splitting by \$ not giving 3 elements but is instead giving 4 elements?
    var array1 = trickyString.split(/\$/);
    document.getElementById("div1").innerHTML = "<b>Length = " + array1.length + "</b>";
    for (var i = 0; i < array1.length; i++) {
        document.getElementById("div1").innerHTML += "<br>" + array1[i];
    }

    var array2 = trickyString.split("$");
    document.getElementById("div2").innerHTML = "<b>Length = " + array2.length + "</b>";
    for (var j = 0; j < array1.length; j++) {
        document.getElementById("div2").innerHTML += "<br>" + array2[j];
    }
}
<button onclick="splitString();return false;">Split a tricky string</button>

<h4>Tricky string</h4>
<div id="div0" style="color:green">sd sewq wee r r ttttt $300 rrtrt utu iwiwi \$500 kjgf ihj \$215 ghi</div>

<h4>Split using \$ as delimiter</h4>
<div id="div1" style="color:red"></div>

<h4>Split using $ as delimiter</h4>
<div id="div2"  style="color:blue"></div>
VLAZ
  • 26,331
  • 9
  • 49
  • 67
Sunil
  • 20,653
  • 28
  • 112
  • 197
  • It seems to work - you get four items. What is your expected result? – VLAZ Oct 18 '18 at 12:55
  • I have 2 `\$` strings in the main string, so shouldn't splitting based on `\$` result in 3 elements? – Sunil Oct 18 '18 at 12:57
  • Possible duplicate of [Reference - What does this regex mean?](https://stackoverflow.com/questions/22937618/reference-what-does-this-regex-mean) – Heretic Monkey Oct 18 '18 at 12:59

2 Answers2

5

Your issue is stemming from the fact that within your regex /\$/, the \$ is being interpreted as requesting the $ to be treated as a literal character.

The regex you should be using is /\\\$/. As seen on regex101.com

\\ matches the character \ literally (case sensitive)
\$ matches the character $ literally (case sensitive)

enter image description here

You are also suffering a similar issue within your string, where you are putting \$, it's being treated as a request to literally use the character $. This can be seen if you do a console.log(trickyString);, you'll notice the \ are not in the output. You'll need to double escape the quote marks:

const trickyString = "sd sewq wee r r ttttt $300 rrtrt utu iwiwi \\$500 kjgf ihj \\$215 ghi;"
Psytronic
  • 6,043
  • 5
  • 37
  • 56
  • 1
    I tried your suggestion, but still I get 1 element instead of 3. – Sunil Oct 18 '18 at 13:01
  • Your input data is wrong. The string `"\$"` is actually resolved as `"$"` since it's interpreted as an escaped dollar sign. – VLAZ Oct 18 '18 at 13:03
  • 1
    @Psytronic, so just 1 backslash before $ is treated as an escape character even though escaping a $ is not required. That makes sense. After changing `trickyString` to include `\\$` in place of '\$` it works. Thanks. – Sunil Oct 18 '18 at 13:09
  • 1
    Correct, JS will always treat a backslash as a request to escape a character. Though escaping the `$` is not required in your string, it *is* required within the regex, as the `$` has special meaning for the regex (end of the string, or alternatively the end of a line if your regex has the `m` flag set) – Psytronic Oct 18 '18 at 13:12
  • Your last comment was awesome since I was missing the point that `$` has a special meaning in regex expression. Its very clear now. Thanks. – Sunil Oct 19 '18 at 03:19
3

The problem is that slashes have special meaning both in a JS String and in a RegEx.

There are two critical parts here:

var trickyString = "sd sewq wee r r ttttt $300 rrtrt utu iwiwi \$500 kjgf ihj \$215 ghi"; 

Should be:

var trickyString = "sd sewq wee r r ttttt $300 rrtrt utu iwiwi \\$500 kjgf ihj \\$215 ghi"; 

Because \$ will be interpreted as an $.

And also:

var array1 = trickyString.split(/\$/);

Should be:

var array1 = trickyString.split(/\\\$/g);

Both because \$ will be interpreted as $, therefore the first \\, and $ has, itself, an special meaning, therefore the second \$.

This is the code I have used:

var trickyString = "sd sewq wee r r ttttt $300 rrtrt utu iwiwi \\$500 kjgf ihj \\$215 ghi"; 

//document.getElementById("div0").innerHTML = trickyString;

function splitString() {
    //Why is splitting by \$ not giving 3 elements but is instead giving 4 elements?
    var array1 = trickyString.split(/\\\$/g);
    document.getElementById("div1").innerHTML = "<b>Length = " + array1.length + "</b>";
    for (var i = 0; i < array1.length; i++) {
        document.getElementById("div1").innerHTML += "<br>" + array1[i];
    }

    var array2 = trickyString.split("$");
    document.getElementById("div2").innerHTML = "<b>Length = " + array2.length + "</b>";
    for (var j = 0; j < array1.length; j++) {
        document.getElementById("div2").innerHTML += "<br>" + array2[j];
    }
}

And these are the results:

Tricky string
sd sewq wee r r ttttt $300 rrtrt utu iwiwi \$500 kjgf ihj \$215 ghi
Split using \$ as delimiter
Length = 3
sd sewq wee r r ttttt $300 rrtrt utu iwiwi
500 kjgf ihj
215 ghi
Split using $ as delimiter
Length = 4
sd sewq wee r r ttttt
300 rrtrt utu iwiwi \
500 kjgf ihj \
Haroldo_OK
  • 6,612
  • 3
  • 43
  • 80
  • I tried your suggestion but it results in 1 string after splitting. It should result in 3 elements after splitting. – Sunil Oct 18 '18 at 13:03
  • Worked okay when I tested. I'm posting the full code for reference. – Haroldo_OK Oct 18 '18 at 13:06
  • 1
    Yes, it works now after changing `\$` to `\\$` in trickyString. I have upvoted your answer. Thanks. – Sunil Oct 18 '18 at 13:11