Spinal Tap Case $ operator

I have a question about the Spinal Tap Case challenge.

The solution says to insert a blank before upper case letters like this:
str = str.replace(/([a-z])([A-Z])/g, '$1 $2');

I try to understand how this works, but I just don’t get it. What does $ do? Why the 1 and 2 in $1 and $2? Which part is the space to be inserted, is it the one between $1 and $2? How does regexp know to insert it before [A-Z]? Shouldn’t the [A-Z] be preceded by ?= to mean lookbehind?

And what is the name of that $ operator? Googling isn’t being helpful even though I’ve searched for three hours.

Thanks for your help.


$1 and $2 are parenthesized submatches, where $1 is the string/character caught by the range in the first parentheses ([a-z]) and $2 is the match caught by second part ([A-Z]) of the regex. If you have more parentheses, you can use $3, $4 etc.

So… with this expression you can catch chunks of two characters where the first one is lowercase and the second one is uppercase. As these ranges are between parentheses, you can use them in your replace() function’s second argument.

let str = 'lowerAndUppercase'
str.replace(/([a-z])([A-Z])/g, '$1 $2')

In the above example, the regex catches rA and dU.

You could also use a function as the second parameter instead of the $1 $2 string:

let str = 'lowerAndUppercase'
str.replace(/([a-z])([A-Z])/g, function(match, s1, s2) {
  return s1 + '  ' + s2

In this case s1 and s2 are the same as $1 and $2 but you have more options to play with them.

I really hope it helps. :wink:


Brilliant!!! I get it now :slight_smile:

function spinalCase(str) {
  // "It's such a fine line between stupid, and clever."
  // --David St. Hubbins
  var nStr = '';
  for(let i = 0; i < str.length; i++) {
    if(/[A-Z]/.test(str[i])) {
      nStr += " " + str[i];
    } else {
      nStr += str[i];
  let arr = [];
  nStr.trim().replace(/_|-/g, " ").split(/\W+/g).forEach(function(ele) {
  return  arr.join("-");

Would really be nice if they explained some of this before requiring it in an answer.


I agree. They went over the $ operator, but not in any way, shape or form in using it the way they did in the answer. Frustrating.

searching everywhere , you have just cleared my doubt and need of explanation too… thanks to you mate

1 Like

Why have you given the extra argument “match” and why doesn’t it work without it???