49

For example suppose I always have a string that is delimited by "-". Is there a way to transform

it-is-a-great-day-today

to

itIsAGreatDayToday

Using RegEx?

mikemaccana
  • 110,530
  • 99
  • 389
  • 494
Hoa
  • 19,858
  • 28
  • 78
  • 107
  • 2
    Hint: in JavaScript a *function* can be supplied as the "replacement" parameter. This function will be evaluated for each match (run in a "global match" mode), and can contain arbitrary code. –  May 03 '12 at 04:53
  • 1
    There seems to be some confusion about what ["proper camel-casing"](http://en.wikipedia.org/wiki/CamelCase) means here. Remember that regular expressions are very particular; consider these inputs (and what the output should be): `foo-bar`, `Foo-Bar`, `FOO-BAR`, `FoO-bAr`, `-foo--bar-`, etc. –  May 03 '12 at 05:24

14 Answers14

90

Yes (edited to support non-lowercase input and Unicode):

function camelCase(input) { 
    return input.toLowerCase().replace(/-(.)/g, function(match, group1) {
        return group1.toUpperCase();
    });
}

See more about "replace callbacks" on MDN's "Specifying a function as a parameter" documentation.

The first argument to the callback function is the full match, and subsequent arguments are the parenthesized groups in the regex (in this case, the character after the the hyphen).

apsillers
  • 112,806
  • 17
  • 235
  • 239
  • 1
    Close, this won't camelCase on `Foo-Bar`, though. –  May 03 '12 at 04:57
  • 2
    @pst sure it will. Although it fails on `politische-ökonomie` since `\w` isn't Unicode-aware. Javascript RegExp also doesn't appear to support `\p{Letter}` or `\p{Letter&}`, so if you want it to work properly you should consider using `/-(.)/g` as the regex. – hobbs May 03 '12 at 05:18
  • @hobbs It'll end in CapWords (`FooBar`). The thing about regular expressions is the are ... very precise. (Actually, it appears from the wiki-definition that `FooBar` and `fooBar` can *both* be considered camelCase/CamelCase...) –  May 03 '12 at 05:19
  • @hobbs: Interesting point. Using `.` instead of `\w` doesn't really hurt anything (I think), since a non-letter won't be affected by `toUpperCase` anyway. Edited. – apsillers May 03 '12 at 05:37
8

Another method using reduce:

function camelCase(str) {
  return str
    .split('-')
    .reduce((a, b) => a + b.charAt(0).toUpperCase() + b.slice(1));
}
Lior Erez
  • 1,852
  • 2
  • 19
  • 24
  • MUCH faster than all the regex based implementations. If you have well structured strings in the first place, and need to be fast (e.g. transforming many keys) then this is very useful... If you have data from a person that can be a mess, use a regex implementation like that in lodash. – Relefant Oct 03 '18 at 18:34
5

You can match on the word character after each dash (-) or the start of the string, or you could simplify by matching the word character after each word boundary (\b):

function camelCase(s) {
  return (s||'').toLowerCase().replace(/(\b|-)\w/g, function(m) {
    return m.toUpperCase().replace(/-/,'');
  });
}
camelCase('foo-bar'); // => 'FooBar'
camelCase('FOo-BaR-gAH'); // => 'FooBarGah'
maerics
  • 151,642
  • 46
  • 269
  • 291
3

Here's a demo

var test = 'It-is-a-great-day-today';

function camelize(str) {
    return str[0].toLowerCase() + str.replace(/-([a-z])/g, function(a, b) {
        return b.toUpperCase();
    }).slice(1);
}

console.log(camelize(test));
Joseph
  • 117,725
  • 30
  • 181
  • 234
  • 2
    This won't camelCase on `Foo-Bar`, though. –  May 03 '12 at 04:57
  • 1
    @apsillers I am not joking. Yes, it ask explicitly `Convert string to camelCase with regular expression?` (See http://en.wikipedia.org/wiki/CamelCase) – Gabriel Santos May 03 '12 at 05:17
  • Thanks for the link; I have always considered it camelCase and CapWords ... but I guess CamelCase also goes ... –  May 03 '12 at 05:22
3

This should also work:

function camelCase(str) {
  return str.replace(/^.|-./g, function(letter, index) {
    return index == 0 ? letter.toLowerCase() : letter.substr(1).toUpperCase();
  });
}

And IMHO it is little bit more efficient since we're not converting whole input string to lowercase first and then convert to uppercase if needed. This function only converts first letter to lowercase and then every character after hyphen - to uppercase.

anubhava
  • 761,203
  • 64
  • 569
  • 643
2

See http://jsfiddle.net/54ZcM/

function camelCase(string) {
    return string.toLowerCase().replace(/(\-[a-zA-Z])/g, function($1) {
        return $1.toUpperCase().replace('-','');
    })
}

alert(camelCase('fOo-BarBA-fo'));
Gabriel Santos
  • 4,934
  • 2
  • 43
  • 74
2

I know this question is a bit old but,

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
2

This works great but someone might be able to clean it up.

var toCamelCase = function(str) {
        // Replace special characters with a space
        str = str.replace(/[^a-zA-Z0-9 ]/g, " ");
        // put a space before an uppercase letter
        str = str.replace(/([a-z](?=[A-Z]))/g, '$1 ');
        // Lower case first character and some other stuff that I don't understand
        str = str.replace(/([^a-zA-Z0-9 ])|^[0-9]+/g, '').trim().toLowerCase();
        // uppercase characters preceded by a space or number
        str = str.replace(/([ 0-9]+)([a-zA-Z])/g, function(a,b,c) {
            return b.trim() + c.toUpperCase();
        });
        return str;
};

console.log(toCamelCase('hyphen~name~ format'));
console.log(toCamelCase('hyphen.name.format'));
console.log(toCamelCase('hyphen-name-format'));
console.log(toCamelCase('Hyphen-Dame-Gormat'));
console.log(toCamelCase('EquipmentClass name'));
console.log(toCamelCase('Equipment className'));
console.log(toCamelCase('equipment class name'));
console.log(toCamelCase(' e    Equipment Class Name'));
console.log(toCamelCase('under9score_name_format'));
console.log(toCamelCase('Enderscore_name_format'));
console.log(toCamelCase('EnderscoreBameFormat'));
console.log(toCamelCase('_EnderscoreBameFormat'));

http://jsbin.com/yageqi/1/edit?js,console

codeBelt
  • 1,727
  • 16
  • 22
1
'it-is-a-great-day-today'.split('-').map(function(x,i){
    return (i?x[0].toUpperCase():x[0]) + x.slice(1).toLowerCase()
}).join('')

Result:

'itIsAGreatDayToday'

Alternatively, .match(/\w+/g) rather than .split('-') -- depending on what you want to do in edge cases like "this--is-a-test".

ninjagecko
  • 88,546
  • 24
  • 137
  • 145
1
var string = "it-is-a-great-day-today";
or
var string = "it_is_a_great_day_today";

var regex = /(_|-)([a-z])/g;

string.toLowerCase().replace(regex, toCamelCase );

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

Output: "itIsAGreatDayToday";
SoEzPz
  • 14,958
  • 8
  • 61
  • 64
0

here is the jsfiddle you can play with to test this http://jsfiddle.net/5n84w/2/

```

/**
 * Function to convert any string to camelCase
 * var regex = 'chetan-Ankola###.com---m13ok#-#alo(*finding!R%S#%-GFF'; 
 * Where [-_ .] is the seperator, you can add eg: '@' too
 * + is to handle repetition of seperator           
 * ? is to take care of preceeding token 
 * match nov(ember)? matches nov and november
 */
var camelCaser = function (str) {
    var camelCased = str.replace(/[-_ .]+(.)?/g, function (match, p) {
        if (p) {
            return p.toUpperCase();
        }
        return '';
    }).replace(/[^\w]/gi, '');
    return camelCased;
};

```

Chetan Ankola
  • 6,915
  • 3
  • 14
  • 6
0

lodash.camelCase can be another option

Sample:

const str = 'it-is-a-great-day-today';
lodash.camelCase(str.split('-'));

result: itIsAGreatDayToday

-1

Better do this guys,

function camelCase(data) {
    var tmp;
    if (data && typeof data === 'object') {
        forEach(data, function (value, key) {
            var tmpvalue = camelCase(key);
            tmp[tmpvalue] = value;
        });
        return tmp;
    } else {
        return data.toLowerCase().replace(/(\_\w)/g, function (m) { return m[1].toUpperCase() }).replace(/(\-\w)/g, function (m) { return m[1].toUpperCase(); });
    }
}

console.log(camelCase("SucCCCess_dfds_dsqsdqs-dsdqs-dqsdqs"));

Works perfectly in any cases.

Lord-Y
  • 132
  • 2
  • 8
-2
$scope.toCamelCase = function(arg){
    var arg = arg.toLowerCase();
    var arr = arg.split("");
    arr[0] = arr[0].toUpperCase();
    return arr.join("");
};