168

With regex (i assume) or some other method, how can i convert things like:

marker-image or my-example-setting to markerImage or myExampleSetting.

I was thinking about just splitting by - then convert the index of that hypen +1 to uppercase. But it seems pretty dirty and was hoping for some help with regex that could make the code cleaner.

No jQuery...

Oscar Godson
  • 31,662
  • 41
  • 121
  • 201
  • 1
    Exact duplicate of [JavaScript RegExp $1 to upper case](http://stackoverflow.com/questions/4969605/javascript-regexp-1-to-upper-case) – mplungjan Jul 12 '11 at 07:49
  • 9
    it is actually, but i searched and never found it probably due to the obscure name. Id suggest keeping this open so people can actually find the answer. "RegExp $1 to uppercase"... no one is going to find it unless they already knew regex IMO – Oscar Godson Jul 12 '11 at 07:56
  • That was easily fixable. I just edited the title – mplungjan Jul 12 '11 at 08:13
  • So a cut and paste of the solutions would have earned me an accepted answer :| – mplungjan Jul 12 '11 at 09:00
  • is there a way to do the exact opposite? – Pavan Jul 12 '18 at 12:36
  • Circa 2019 It's ALWAYS a good DRY idea for such basic questions to see what is in sindresorhus' library first, https://npms.io/search?q=author%3Asindresorhus+camel Sindresorhus has literally hundreds of small, single purpose, and maintained packages covering all the basics and more – DKebler Feb 21 '19 at 20:08
  • No jQuery... this should be or get at least a standard nowadays – aProgger Oct 16 '21 at 10:12

16 Answers16

312

Try this:

var camelCased = myString.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); });

The regular expression will match the -i in marker-image and capture only the i. This is then uppercased in the callback function and replaced.

Paolo Moretti
  • 54,162
  • 23
  • 101
  • 92
  • 62
    FYI, here's the opposite : `myString.replace(/([a-z][A-Z])/g, function (g) { return g[0] + '-' + g[1].toLowerCase() });` – Cyril N. Jul 06 '12 at 12:45
  • I think that the parameter should be renamed to "m", like "match". One can quickly write something like : `myString.replace(/-([a-z])/i, function (i) { return i[1].toUpperCase() });` – programaths Jul 15 '13 at 14:34
  • 9
    It would be a good idea to make your regex more robust by adding the `i` flag. Without it, your pattern misses "capitalized-Parts" (won't be changed into "capitalizedParts"). Also, I personally prefer the improved readability of multiple parameters, but that's obviously a matter of style. All in all, I'd go with `.replace( /-([a-z])/gi, function ( $0, $1 ) { return $1.toUpperCase(); } );`. – hashchange Mar 06 '15 at 11:35
  • To add upon this, if you want to camel case *space separated* words as well, the following would work: `var camelCased = myString.replace(/(-+|\s+)\w/g, function (g) { return g[1].toUpperCase(); });` – wolfram77 Jan 26 '16 at 11:57
  • @wolfram77, You include multiple dashes/space characters in the regexp, then uppercase the second character of the match, meaning if the second character is a space or dash, it is the one getting uppercased. How about this: `var camelCased = myString.replace(/(-+|\s+)\w/g, function (g) { return g[g.length - 1].toUpperCase(); });`? – trysis Jul 09 '16 at 16:29
  • @trysis i deliberately made a mistake to see if anyone can notice. good! :) – wolfram77 Jul 09 '16 at 19:11
  • 4
    a wee bit shorter: `str.replace(/-./g, c => c. substring(1).toUpperCase())` – StLia Jan 02 '20 at 13:41
  • @StLia note (for others as you probably already know): this also matches marker-Image, my-Example-Setting, my-1st-Example-With-a-Number, ... Someone might not want that :) – aProgger Oct 16 '21 at 10:12
54

This is one of the great utilities that Lodash offers if you are enlightened and have it included in your project.

var str = 'my-hyphen-string';
str = _.camelCase(str);
// results in 'myHyphenString'
ShadeTreeDeveloper
  • 1,553
  • 2
  • 12
  • 20
20

You can get the hypen and the next character and replace it with the uppercased version of the character:

var str="marker-image-test";
str.replace(/-([a-z])/g, function (m, w) {
    return w.toUpperCase();
});
mck89
  • 18,918
  • 16
  • 89
  • 106
  • 4
    Nice - I went with this method but ES6'd it into >> str.replace(/-([a-z])/g, (x, up) => up.toUpperCase()) – ConorLuddy Nov 01 '18 at 10:54
15

Here's my version of camelCase function:

var camelCase = (function () {
    var DEFAULT_REGEX = /[-_]+(.)?/g;

    function toUpper(match, group1) {
        return group1 ? group1.toUpperCase() : '';
    }
    return function (str, delimiters) {
        return str.replace(delimiters ? new RegExp('[' + delimiters + ']+(.)?', 'g') : DEFAULT_REGEX, toUpper);
    };
})();

It handles all of the following edge cases:

  • takes care of both underscores and hyphens by default (configurable with second parameter)
  • string with unicode characters
  • string that ends with hyphens or underscore
  • string that has consecutive hyphens or underscores

Here's a link to live tests: http://jsfiddle.net/avKzf/2/

Here are results from tests:

  • input: "ab-cd-ef", result: "abCdEf"
  • input: "ab-cd-ef-", result: "abCdEf"
  • input: "ab-cd-ef--", result: "abCdEf"
  • input: "ab-cd--ef--", result: "abCdEf"
  • input: "--ab-cd--ef--", result: "AbCdEf"
  • input: "--ab-cd-__-ef--", result: "AbCdEf"

Notice that strings that start with delimiters will result in a uppercase letter at the beginning. If that is not what you would expect, you can always use lcfirst. Here's my lcfirst if you need it:

function lcfirst(str) {
    return str && str.charAt(0).toLowerCase() + str.substring(1);
}
Joon
  • 9,346
  • 8
  • 48
  • 75
9

Use String's replace() method with a regular expression literal and a replacement function.

For example:

'uno-due-tre'.replace(/-./g, (m) => m[1].toUpperCase()) // --> 'unoDueTre'

Explanation:

  • 'uno-due-tre' is the (input) string that you want to convert to camel case.
  • /-./g (the first argument passed to replace()) is a regular expression literal.
    • The '-.' (between the slashes) is a pattern. It matches a single '-' character followed by any single character. So for the string 'uno-due-tre', the pattern '-.' matches '-d' and '-t' .
    • The 'g' (after the closing slash) is a flag. It stands for "global" and tells replace() to perform a global search and replace, ie, to replace all matches, not just the first one.
  • (m) => m[1].toUpperCase() (the second argument passed to replace()) is the replacement function. It's called once for each match. Each matched substring is replaced by the string this function returns. m (the first argument of this function) represents the matched substring. This function returns the second character of m uppercased. So when m is '-d', this function returns 'D'.
  • 'unoDueTre' is the new (output) string returned by replace(). The input string is left unchanged.
ma11hew28
  • 121,420
  • 116
  • 450
  • 651
4

This doesn't scream out for a RegExp to me. Personally I try to avoid regular expressions when simple string and array methods will suffice:

let upFirst = word => 
  word[0].toUpperCase() + word.toLowerCase().slice(1)

let camelize = text => {
  let words = text.split(/[-_]/g) // ok one simple regexp.
  return words[0].toLowerCase() + words.slice(1).map(upFirst)
}

camelize('marker-image') // markerImage
3

Here is my implementation (just to make hands dirty)

/**
 * kebab-case to UpperCamelCase
 * @param {String} string
 * @return {String}
 */
function toUpperCamelCase(string) {
  return string
    .toLowerCase()
    .split('-')
    .map(it => it.charAt(0).toUpperCase() + it.substring(1))
    .join('');
}
Jagjot
  • 5,816
  • 2
  • 24
  • 41
D.Dimitrioglo
  • 3,413
  • 2
  • 21
  • 41
2
// Turn the dash separated variable name into camelCase.
str = str.replace(/\b-([a-z])/g, (_, char) => char.toUpperCase());
alex
  • 479,566
  • 201
  • 878
  • 984
1

Here is another option that combines a couple answers here and makes it method on a string:

if (typeof String.prototype.toCamel !== 'function') {
  String.prototype.toCamel = function(){
    return this.replace(/[-_]([a-z])/g, function (g) { return g[1].toUpperCase(); })
  };
}

Used like this:

'quick_brown'.toCamel(); // quickBrown
'quick-brown'.toCamel(); // quickBrown
John Naegle
  • 8,077
  • 3
  • 38
  • 47
0

Another take.

Used when...

var string = "hyphen-delimited-to-camel-case"
or
var string = "snake_case_to_camel_case"


function toCamelCase( string ){
  return string.toLowerCase().replace(/(_|-)([a-z])/g, toUpperCase );
}

function toUpperCase( string ){
  return string[1].toUpperCase();
}

Output: hyphenDelimitedToCamelCase
SoEzPz
  • 14,958
  • 8
  • 61
  • 64
0

is also possible use indexOf with recursion for that task.

input some-foo_sd_dsd-weqe
output someFooSdDsdWeqe

comparison ::: measure execution time for two different scripts:

$ node camelCased.js
someFooSdDsdWeqe
test1: 2.986ms
someFooSdDsdWeqe
test2: 0.231ms

code:

console.time('test1');
function camelCased (str) {

        function check(symb){

            let idxOf = str.indexOf(symb);
            if (idxOf === -1) {
                return str;
            }

            let letter = str[idxOf+1].toUpperCase();
            str = str.replace(str.substring(idxOf+1,idxOf+2), '');
            str = str.split(symb).join(idxOf !== -1 ? letter : '');

            return camelCased(str);
        }       

        return check('_') && check('-');

    }

console.log(camelCased ('some-foo_sd_dsd-weqe'));
console.timeEnd('test1');



console.time('test2');

    function camelCased (myString){
     return myString.replace(/(-|\_)([a-z])/g, function (g) { return  g[1].toUpperCase(); });
   }


console.log(camelCased ('some-foo_sd_dsd-weqe'));
console.timeEnd('test2');
Anja Ishmukhametova
  • 1,535
  • 16
  • 14
0

Just a version with flag, for loop and without Regex:

function camelCase(dash) { 

  var camel = false;
  var str = dash;
  var camelString = '';

  for(var i = 0; i < str.length; i++){
    if(str.charAt(i) === '-'){
      camel = true;

    } else if(camel) {
      camelString += str.charAt(i).toUpperCase();
      camel = false;
    } else {
      camelString += str.charAt(i);
    }
  } 
  return camelString;
}
Hunter
  • 3,080
  • 20
  • 23
0

You can use camelcase from NPM.

npm install --save camelcase

const camelCase = require('camelcase');
camelCase('marker-image'); // => 'markerImage';
camelCase('my-example-setting'); // => 'myExampleSetting';
Ilyich
  • 4,966
  • 3
  • 39
  • 27
Lanil Marasinghe
  • 2,785
  • 24
  • 24
0

Use this if you allow numbers in your string.

Obviously the parts that begin with a number will not be capitalized, but this might be useful in some situations.

function fromHyphenToCamelCase(str) {
  return str.replace(/-([a-z0-9])/g, (g) => g[1].toUpperCase())
}

function fromHyphenToCamelCase(str) {
  return str.replace(/-([a-z0-9])/g, (g) => g[1].toUpperCase())
}

const str1 = "category-123";
const str2 = "111-222";
const str3 = "a1a-b2b";
const str4 = "aaa-2bb";

console.log(`${str1} => ${fromHyphenToCamelCase(str1)}`);
console.log(`${str2} => ${fromHyphenToCamelCase(str2)}`);
console.log(`${str3} => ${fromHyphenToCamelCase(str3)}`);
console.log(`${str4} => ${fromHyphenToCamelCase(str4)}`);
cbdeveloper
  • 27,898
  • 37
  • 155
  • 336
0

You can also use string and array methods; I used trim to avoid any spaces.

const properCamel = (str) =>{

  const lowerTrim = str.trim().toLowerCase(); 

  const array = lowerTrim.split('-');

  const firstWord = array.shift();

  const caps = array.map(word=>{

    return word[0].toUpperCase() + word.slice(1);

  })

  caps.unshift(firstWord)

  return caps.join('');

}
0

This simple solution takes into account these edge cases.

  • Single word
  • Single letter
  • No hyphen
  • More than 1 hyphen

const toCamelCase = (text) => text.replace(/(.)([^-|$]*)[-]*/g, (_,letter,word) => `${letter.toUpperCase()}${word.toLowerCase()}`)