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.
$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:
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) {
arr.push(ele.toLowerCase());
})
return arr.join("-");
}