0

Pre: I have my own library, where I work with namespaced modules and classes in Coffescript. this works like in Ruby "namspace::module::class", since '::' is not allowed as class name I replace Module::ClassName with Module$$ClassName -> replace(/\$\$/g,'::'), fine.

Now i struggled doing it reverse: replace(/::/g,'$$') results in Module$ClassName having only one Dollar ($)

So i played a around a bit

a="a:a::b:b::c:c"
a.replace(':','$')         #-> "a$a::b:b::c:c"  clear only first 
a.replace(/:/g,'$')        #-> "a$a$$b$b$$c$c"  better, but wrong we want '::' only 
a.replace(/::/g,'$$')      #-> "a:a$b:b$c:c"    suprise; where is the 2nd Dollar? 
a.replace("::",'$$')       #-> "a:a$b:b::c:c"   try no regexp since dollar has an other meaning? fails only one $
a.replace(/::/g,'\$\$')    #-> "a:a$b:b$c:c"    ESC the guys? nope  
a.replace(/::/g,"\\$\\$")  #-> "a:a\$\$b:b\$\$c:c" ESC ESC to get into the deeper?
                           #   and then replace(/\\\$/g,'$') ? overkill  
a.replace(/::/g,'$$$')     #-> "a:a$$b:b$$c:c"  bingo, but why? 
# trying more
a.replace(/::/g,'$$$$')    #-> "a:a$$b:b$$c:c"  2 get one? one stays alone 
a.replace(/::/g,'$$$$$')   #-> "a:a$$$b:b$$$c:c"  seems so

After all, is logic (and I wonder why I never had the prob before).

So I think (am sure) that '$$' escapes to one '$' because '$n' references to matching groups - but even if there is no regexp in?

halfbit
  • 3,773
  • 2
  • 34
  • 47
  • 1
    You have a regex replacement almost everywhere. In the replacement string, literal `$` must be represented with `$$`. What do you mean by *if there is no regexp in*? – Wiktor Stribiżew Nov 25 '15 at 16:49
  • *"but even if there is no regexp in?"* Uh? `/::/g` is a regular expression. I think the [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_string_as_a_parameter) is pretty clear. – Felix Kling Nov 25 '15 at 16:53
  • I think he means even if there's no capture group. – Barmar Nov 25 '15 at 16:58
  • I meant ex. #4 a.replace("::",'$$') " – halfbit Nov 26 '15 at 19:50

3 Answers3

3

Even if you don't have any capture groups, $ can be used in the replacement string. $& refers to everything that was matched by the regexp, $` refers to everything before the match, and $' refers to everything after the match. So $ is always treated specially, and $$ means just a single $.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • I dont know how many times I was on JSs replace docu page - just to get remembered: Javascript match capture group: "$n" not "\n", i never noticed $' and $' (and '$$') – halfbit Nov 26 '15 at 19:24
2

The reason is because $ is a special character in the second parameter of replace. See 'Specifying a string as a parameter' in https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace

Tennyson H
  • 1,705
  • 15
  • 28
1

Why do I need “$$$” (three dollar) if I want “$$” (two dollar) as replace string

In fact, you need 4 $ in the replacement string. To replace with a literal $, you need two $s, as one $ "escapes" the other.

Thus, you need

var a = "some::var";
a = a.replace(/::/g,'$$$$'); // this will replace `::` with `$$`
document.body.innerHTML = a;

If you add an odd $, it will be treated as a literal, or omitted, or whatever a specific browser wants to do with this "wild" escaping symbol. Thus, it is safer to use an even number of $s in the replacement pattern.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563