It’s the combination of String.prototype.match(), RegExp, and String.prototype.replace() that gives us the solution to coverting a kebab case string to camel case string in JS.

Convert kebab case to camel case in JS

For this exercise, we’ll use a regex that looks like this: /-./. Let’s first understand how it works. Given a string:

let str = '-abcd';

… let’s try to match the above string against the /-./ regex.

let str = '-abcd';
str.match(/-./);
/* returns
["-a", index: 0, input: "-abcd", groups: undefined]
*/

Compare the above result with:

let str = 'abcd';
str.match(/-./);
/* returns
null
*/

Given a string, the match() method takes a RegExp literal object.

If the passed-in argument is not a RegExp object…

let str = '-abcd';
str.match("-.");

… the match() method will convert the passed-in argument to a RegExp object behind the scenes.

If the g flag was passed to RegExp literal, the match() method will return an array with all the matching results, without the capturing group data.

Otherwise, if no g flag was used, the returned result is an array with the first matching value and the capturing group data.

If there are no matches, the returned value is null.

Let’s see what happens if we use the capturing groups (the g flag):

1
2
3
4
5
let str = '-abcd';
str.match(/-./g);
/* returns
["-a"]
*/

Compare the above result with:

1
2
3
4
5
let str = 'abcd';
str.match(/-./g);
/* returns
null
*/

We can conclude that if there are no matches, null will get returned. If there is a match, it will get returned in an array, as a string.

Now that we understand the String.prototype.match() method, we need to discuss the String.prototype.replace() method.

The replace() method works like this: it takes a matchingSubstring as its first parameter, and it also takes a replacementSubstring, so:

let replacedString = str.replace(matchingSubstring, replacementSubstring);

Thus, for example, given this string: -abcde, let’s say we’re looking for the substring of -a. So, the value of the matchingSubstring is -a. That’s what we’re looking for.

We’ll replace it with a capital A, so:

let replacedString = str.replace(/-./, "A");

With the above code, we’re replacing the first cocurence of a - followed by any character, with a letter A.

For example:

1
2
3
4
5
6
let str = '-abcde';
let replacedString = str.replace(/-./, "A");
console.log(replacedString);
/* returns:
Abcde
*/

Now let’s put that into a function:

1
2
3
4
function replaceSubstr(str) {
    let replacedStr = str.replace(/-./, "A")
    console.log(replacedStr);
}

With this function defined, we can now pass it any string and update it as explained, like this:

replaceSubstr('-a-a-a'); // returns: A-a-a

So, obviously, the String.prototype.replace() only takes the first occurence of the matching substring. This means that we need to add the g flag to our function:

1
2
3
4
5
function replaceSubstr(str) {
    let replacedStr = str.replace(/-./g, "A")
    console.log(replacedStr);
}
replaceSubstr('-a-a-a'); // returns: "AAA"

Great, we’re almost done! Now all we have to do is replace the string of two characters, for example -a, with the second character uppercased, that is, with an “A”. Because the . in the regex /-./ stands for any character, we will have the following effect:

  • -a replaced with A
  • -b replaced with B
  • -c replaced with C
  • etc.

To achieve this effect, we’ll reassign the matching characters with the second member of our match:

1
2
3
4
5
6
let testStr = '-a-b-c';
function replaceSubstr(str) {
    let replacedStr = str.replace(/-./g, match => match[1].toUpperCase())
    console.log(replacedStr);
}
replaceSubstr(testStr); // returns: "ABC"

It’s great understanding exactly what is happening in each line of our code, isn’t it? Therefore, to be completely certain that we fully understand this code, let’s log out the matches as follows:

1
2
3
4
5
6
7
8
let str = "what-is-it";
function kebabToCC(str) {
  console.log(str.match(/-./g));
  return str.replace(/-./g, match => match[1].toUpperCase());
}
kebabToCC('what-is-it');
(2) ["-i", "-i"]
"whatIsIt"



Note:
This exercise comes from Book 3 of my book series on JS, available on Leanpub.com.