Convert a String to Spinal Case - javascript

Challenge: Convert a string to spinal case. Spinal case is all-lowercase-words-joined-by-dashes
function spinalCase(str) {
var res = str.replace(/\s/g, "-")
var result = res.replace(/_/g, '').toLowerCase();
return result;
}
Code works only if there are spaces between strings or if there are no underscores. I am stuck trying to pass the rest of the test-cases, does anybody else have any tips or ideas in mind?
spinalCase("This Is Spinal Tap") should return "this-is-spinal-tap".
spinalCase("thisIsSpinalTap") should return "this-is-spinal-tap".
spinalCase("The_Andy_Griffith_Show") should return "the-andy-griffith-show".
spinalCase("Teletubbies say Eh-oh") should return "teletubbies-say-eh-oh".
spinalCase("AllThe-small Things") should return "all-the-small-things".

You may remove all non-alphanumeric chars at the start/end of the string, replace these consecutive chars with - anywhere else, then you may insert a hyphen in between lower- and uppercase letters, and then turn all to lower case.
function spinalCase(str) {
return str.replace(/^[\W_]+|[\W_]+$|([\W_]+)/g, function ($0, $1) {
return $1 ? "-" : "";
}).replace(/([a-z])(?=[A-Z])/g, '$1-').toLowerCase();
}
console.log(spinalCase("This Is Spinal Tap")); // "this-is-spinal-tap".
console.log(spinalCase("thisIsSpinalTap")); // "this-is-spinal-tap".
console.log(spinalCase("The_Andy_Griffith_Show")); // "the-andy-griffith-show".
console.log(spinalCase("Teletubbies say Eh-oh")); //"teletubbies-say-eh-oh".
console.log(spinalCase("AllThe-small Things")); // "all-the-small-things".
Details
.replace(/^[\W_]+|[\W_]+$|([\W_]+)/g, function ($0, $1) { return $1 ? "-" : ""; }) - removes all non-alphanumeric chars at the start (^[\W_]+)/end ([\W_]+$) of the string, replace these consecutive chars with - anywhere else (([\W_]+))
.replace(/([a-z])(?=[A-Z])/g, '$1-') - insert a hyphen in between lower- and uppercase letters.

Answer for this question version: When input string use camel-case then we not need dictionary and can use regexp only:
let s="exampleStringTwoThe-smallThing";
let r=s.replace(/([A-Z][a-z\-]*)/g, ' $1');
console.log(r);
For current question version:
s.replace(/( |_)+/g,'-').replace(/([a-z])(?=[A-Z])/g, '$1-').toLowerCase()
function spinalCase(s) {
return s.replace(/( |_)+/g,'-').replace(/([a-z])(?=[A-Z])/g, '$1-').toLowerCase();
}
console.log( spinalCase("This Is Spinal Tap") ) // should return "this-is-spinal-tap".
console.log( spinalCase("thisIsSpinalTap") ) // should return "this-is-spinal-tap".
console.log( spinalCase("The_Andy_Griffith_Show") ) // should return "the-andy-griffith-show".
console.log( spinalCase("Teletubbies say Eh-oh") ) // should return "teletubbies-say-eh-oh".
console.log( spinalCase("AllThe-small Things") ) // should return "all-the-small-things".
I improve solution by remove on replace using Wiktor answer

Related

Regex to replace single or multiple occurrence of hyphen

I have written below function to convert space with hyphen or reverse
space with hyphen str.trim().replace(/\s+/g, '-')
hyphen with space str.replace(/\-/g,' ')
But now I am trying to replace single hyphen with double hyphen, I can't use point 1 function because it convert single/multiple occurrence instead of single.
Is there any way to write regex which do 3 operation in single formula
convert forward slash with underscore replace(/\//g, '_')
convert space with single hyphen
convert single hyphen with multiple hyphen
e.g.
regex 1 change
"Name/Er-Gourav Mukhija" into "Name_Er--Gourav-Mukhija"
regex 2 do reverse of it.
You could use a callback function instead of a replace string. That way you can specify and replace all characters at once.
const input = 'Name/Er-Gourav Mukhija';
const translate = {
'/': '_',
'-': '--',
' ': '-',
};
const reverse = {
'_': '/',
'--': '-',
'-': ' ',
};
// This is just a helper function that takes
// the input string, the regex and the object
// to translate snippets.
function replaceWithObject( input, regex, translationObj ) {
return input.replace( regex, function( match ) {
return translationObj[ match ] ? translationObj[ match ] : match;
} );
}
function convertString( input ) {
// Search for /, - and spaces
return replaceWithObject( input, /(\/|\-|\s)/g, translate );
}
function reverseConvertedString( input ) {
// Search for _, -- and - (the order here is very important!)
return replaceWithObject( input, /(_|\-\-|\-)/g, reverse );
}
const result = convertString( input );
console.log( result );
console.log( reverseConvertedString( result ) );
It is not possible to write a Regex formula which does conditional replacements (ie a->b, c->d). I would instead try to create two statements to replace " " -> "--" and "/" -> "_".
You can use your existing code for both of these operations. I would recommend using this site for building and testing Regexes in the future.
Consider var str = "Name/Er-Gourav Mukhija"
To convert forward slash with underscore, as you mentioned use replace(/\//g, '_')
To convert space with single hyphen, use replace(/\s+/g, '-')
To convert single hyphen to double hyphen, use replace(/\-/g, '--').
All these 3 can be combined into:
str.replace(/\//g, '_').replace(/\s+/g, '-').replace(/\-/g, '--')
You should use a loop to do all at once:
str = str.split("");
var newStr = "";
str.forEach(function (curChar) {
switch(curChar) {
case " ":
newStr += "-";
break;
case "/":
newStr += "_";
break;
case "-":
newStr += "--";
break;
default:
newStr += curChar;
}
});
str = newStr;
Feel free to turn this into a function if you like. I also havven't made it do the reverse, but all you'd need to do is replace the assignment strings with the case strings in the switch () statement.
There's no way to do it all with regex, as your later regex will overwrite your first regex in at least one case no matter how you write it.

Capitalize first letter of each word in JS

I'm learning how to capitalize the first letter of each word in a string and for this solution I understand everything except the word.substr(1) portion. I see that it's adding the broken string but how does the (1) work?
function toUpper(str) {
return str
.toLowerCase()
.split(' ')
.map(function(word) {
return word[0].toUpperCase() + word.substr(1);
})
.join(' ');
}
console.log(toUpper("hello friend"))
The return value contain 2 parts:
return word[0].toUpperCase() + word.substr(1);
1) word[0].toUpperCase(): It's the first capital letter
2) word.substr(1) the whole remain word except the first letter which has been capitalized. This is document for how substr works.
Refer below result if you want to debug:
function toUpper(str) {
return str
.toLowerCase()
.split(' ')
.map(function(word) {
console.log("First capital letter: "+word[0]);
console.log("remain letters: "+ word.substr(1));
return word[0].toUpperCase() + word.substr(1);
})
.join(' ');
}
console.log(toUpper("hello friend"))
Or you could save a lot of time and use Lodash
Look at
https://lodash.com/docs/4.17.4#startCase -added/edited-
https://lodash.com/docs/4.17.4#capitalize
Ex.
-added/edited-
You may what to use startCase, another function for capitalizing first letter of each word.
_.startCase('foo bar');
// => 'Foo Bar'
and capitalize for only the first letter on the sentence
_.capitalize('FRED');
// => 'Fred'
Lodash is a beautiful js library made to save you a lot of time.
There you will find a lot of time saver functions for strings, numbers, arrays, collections, etc.
Also you can use it on client or server (nodejs) side, use bower or node, cdn or include it manually.
Here is a quick code snippet. This code snippet will allow you to capitalize the first letter of a string using JavaScript.
function capitlizeText(word)
{
return word.charAt(0).toUpperCase() + word.slice(1);
}
The regexp /\b\w/ matches a word boundary followed by a word character. You can use this with the replace() string method to match then replace such characters (without the g (global) regexp flag only the first matching char is replaced):
> 'hello my name is ...'.replace(/\b\w/, (c) => c.toUpperCase());
'Hello my name is ...'
> 'hello my name is ...'.replace(/\b\w/g, (c) => c.toUpperCase());
'Hello My Name Is ...'
function titleCase(str) {
return str.toLowerCase().split(' ').map(x=>x[0].toUpperCase()+x.slice(1)).join(' ');
}
titleCase("I'm a little tea pot");
titleCase("sHoRt AnD sToUt");
The major part of the answers explains to you how works the substr(1). I give to you a better aproach to resolve your problem
function capitalizeFirstLetters(str){
return str.toLowerCase().replace(/^\w|\s\w/g, function (letter) {
return letter.toUpperCase();
})
}
Explanation:
- First convert the entire string to lower case
- Second check the first letter of the entire string and check the first letter that have a space character before and replaces it applying .toUpperCase() method.
Check this example:
function capitalizeFirstLetters(str){
return str.toLowerCase().replace(/^\w|\s\w/g, function (letter) {
return letter.toUpperCase();
})
}
console.log(capitalizeFirstLetters("a lOt of words separated even much spaces "))
Consider an arrow function with an implicit return:
word => `${word.charAt(0).toUpperCase()}${word.slice(1).toLowerCase()}`
This will do it in one line.
Using ES6
let captalizeWord = text => text.toLowerCase().split(' ').map( (i, j) => i.charAt(0).toUpperCase()+i.slice(1)).join(' ')
captalizeWord('cool and cool')
substr is a function that returns (from the linked MDN) a new string containing the extracted section of the given string (starting from the second character in your function). There is a comment on the polyfill implementation as well, which adds Get the substring of a string.
function titlecase(str){
let titlecasesentence = str.split(' ');
titlecasesentence = titlecasesentence.map((word)=>{
const firstletter = word.charAt(0).toUpperCase();
word = firstletter.concat(word.slice(1,word.length));
return word;
});
titlecasesentence = titlecasesentence.join(' ');
return titlecasesentence;
}
titlecase('this is how to capitalize the first letter of a word');
const capitalize = str => {
if (typeof str !== 'string') {
throw new Error('Invalid input: input must of type "string"');
}
return str
.trim()
.replace(/ {1,}/g, ' ')
.toLowerCase()
.split(' ')
.map(word => word[0].toUpperCase() + word.slice(1))
.join(' ');
};
sanitize the input string with trim() to remove whitespace from the leading and trailing ends
replace any extra spaces in the middle with a RegExp
normalize and convert it all toLowerCase() letters
convert the string to an array split on spaces
map that array into an array of capitalized words
join(' ') the array with spaces and return the newly capitalized string
Whole sentence will be capitalize only by one line
"my name is John".split(/ /g).map(val => val[0].toUpperCase() + val.slice(1)).join(' ')
Output "My Name Is John"
A nice simple solution, using pure JavaScript. JSFiddle
function initCap(s) {
var result = '';
if ((typeof (s) === 'undefined') || (s == null)) {
return result;
}
s = s.toLowerCase();
var words = s.split(' ');
for (var i = 0; i < words.length; ++i) {
result += (i > 0 ? ' ' : '') +
words[i].substring(0, 1).toUpperCase() +
words[i].substring(1);
}
return result;
}
Here is an example of how substr works: When you pass in a number, it takes a portion of the string based on the index you provided:
console.log('Testing string'.substr(0)); // Nothing different
console.log('Testing string'.substr(1)); // Starts from index 1 (position 2)
console.log('Testing string'.substr(2));
So, they are taking the first letter of each word, capitalizing it, and then adding on the remaining of the word. Ance since you are only capitalizing the first letter, the index to start from is always 1.
In word.substr(i), the param means the index of the word. This method cuts the word from the letter whose index equals i to the end of the word.
You can also add another param like word.substr(i, len), where len means the length of the character segmentation. For example:
'abcde'.substr(1, 2) → bc.
function toTitleCase(str)
{
return str.replace(/\w\S*/g, function(txt){return
txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
}
Just map through if an array set the first letter as uppercase and concatenate with other letters from index 1.
The array isn't your case here.
const capitalizeNames = (arr) => {
arr.map((name) => {
let upper = name[0].toUpperCase() + name.substr(1)
console.log(upper)
})
}
Here's another clean way of Capitalizing sentences/names/... :
const capitalizeNames =(name)=>{
const names = name.split(' ') // ['kouhadi','aboubakr',essaaddik']
const newCapName = [] // declaring an empty array
for (const n of names){
newCapName.push(n.replace(n[0], n[0].toUpperCase()));
}
return newCapName.join(' ')
}
capitalizeNames('kouhadi aboubakr essaaddik'); // 'Kouhadi Aboubakr Essaaddik'
You could use these lines of code:
function toUpper(str) {
return [str.split('')[0].toUpperCase(), str.split('').slice(1, str.split('').length).join("")].join("")
}
Basically it will split all characters, slice it, create a new array without the first entry/character and replace the first entry/character with an uppercase verion of the character.
(Yes, this was tested and it works on Edge, Chrome and newer versions of Internet Explorer.)
This is probably not the greatest answer, but hopefully it works well enough for you.

placing dashes in a string

function dashes(str) {
str = str.replace(/_/g,' ').replace(/\s+/g,"-").toLowerCase();
return str;
}
//test cases
dashes("thisCakeIsDelicious");
dashes("TheBig cat was Boastful");
the desired output respectively are: "this-cake-is-delicious" and "the-big-cat-was-boastful".
How do i put a space between "TheBig" without contradicting the space before "Boastful". I have tried regex particular capital letters but as you can see Big and Boastful start with B.
This should work, but I'm not absolutely sure about the requirements so I decided to divide by word not by letter (so LLLLie will result in llllie, not l-l-l-lie)
([a-z]+)([A-Z]{1})|(\s)
Matches:
([a-z]+): 1 or more lowercase letter
([A-Z]{1}): 1 uppercase letter
(\s+): one or more whitespace character (equal to [\r\n\t\f\v ])
var dasher = function(str) {
return str
.trim()
.replace(/([a-z]+)([A-Z]{1})|(\s+)/g, '$1-$2')
.toLowerCase();
}
console.log(dasher('thisCakeIsDelicious'));
console.log(dasher('TheBig cat was Boastful'));
console.log(dasher('The cakeIsA LLLLLie'));
console.log(dasher(' JeremySpoke inClass Today'));
x = "thisCakeIsDelicious";
x.replace(/([a-z](?=[A-Z]))| /g, '$1-');
results in
this-Cake-Is-Delicious,
and
x = "TheBig cat was Boastful";
x.replace(/([a-z](?=[A-Z]))| /g, '$1-');
results in
The-Big-cat-was-Boastful
You could use a callback in the replace function
function dashes(str) {
return str.replace(/(?!^)(\s?[A-Z\s+])/g, function(x) {
return '-' + x.trim();
}).toLowerCase();
}
//test cases
console.log( dashes("thisCakeIsDelicious") );
console.log( dashes("TheBig cat was Boastful") );

Replace underscores with spaces and capitalize words

I am attempting to create a way to convert text with lowercase letters and underscores into text without underscores and the first letter of each word is capitalized.
ex;
options_page = Options Page
At this page: How to make first character uppercase of all words in JavaScript?
I found this regex:
key = key.replace(/(?:_| |\b)(\w)/g, function(key, p1) { return p1.toUpperCase()});
This does everything except replace the underscores with spaces. I have not really tried anything because I am not that familiar with regexpressions.
How can I adjust this regex so it replaces underscores with spaces?
This should do the trick:
function humanize(str) {
var i, frags = str.split('_');
for (i=0; i<frags.length; i++) {
frags[i] = frags[i].charAt(0).toUpperCase() + frags[i].slice(1);
}
return frags.join(' ');
}
console.log(humanize('humpdey_dumpdey'));
// > Humpdey Dumpdey
repl
http://repl.it/OnE
Fiddle:
http://jsfiddle.net/marionebl/nf4NG/
jsPerf:
Most test data: http://jsperf.com/string-transformations
All versions plus _.str: http://jsperf.com/string-transformations/3
Since Lodash 3.1.0, there's a _.startCase([string='']) method that transforms any case into capitalized words (start case):
_.startCase('hello_world'); // returns 'Hello World'
_.startCase('hello-world'); // returns 'Hello World'
_.startCase('hello world'); // returns 'Hello World'
There are other useful methods in the String section of Lodash. Read the documentation here.
These are two different tasks, so two different regexes is the best solution:
key = key.replace(/_/g, ' ').replace(/(?: |\b)(\w)/g, function(key) { return key.toUpperCase()});
To ensure even all capital words is processed. You can add .toLowerCase() before the very first .replace:
console.log('TESTING_WORD'.toLowerCase().replace(/_/g, ' ')
.replace(/(?: |\b)(\w)/g, function(key, p1) {
return key.toUpperCase();
}));
Simply add .replace('_',' ')
Like this
function toCamel(string){
return string.replace(/(?:_| |\b)(\w)/g, function($1){return $1.toUpperCase().replace('_',' ');});
}
Another alternative:
camel = "options_page".replace(/(^|_)(\w)/g, function ($0, $1, $2) {
return ($1 && ' ') + $2.toUpperCase();
});
console.log(camel);
The regular expression:
(^|_) beginning of the input OR "_" ($1)
(\w) a word character (short for [a-zA-Z0-9_]) ($2)
g all occurrences (global)
More about regular expressions : http://www.javascriptkit.com/javatutors/redev.shtml.
Here:
var str = 'Lorem_ipsum_dolor_sit_amet,_consectetur____adipiscing_elit.'
str = str.replace(/_{1,}/g,' ').replace(/(\s{1,}|\b)(\w)/g, function(m, space, letter)
{
return space + letter.toUpperCase();
})
console.log(str);

Converting any string into camel case

How can I convert a string into camel case using javascript regex?
EquipmentClass name or
Equipment className or equipment class name or Equipment Class Name
should all become: equipmentClassName.
Looking at your code, you can achieve it with only two replace calls:
function camelize(str) {
return str.replace(/(?:^\w|[A-Z]|\b\w)/g, function(word, index) {
return index === 0 ? word.toLowerCase() : word.toUpperCase();
}).replace(/\s+/g, '');
}
camelize("EquipmentClass name");
camelize("Equipment className");
camelize("equipment class name");
camelize("Equipment Class Name");
// all output "equipmentClassName"
Edit: Or in with a single replace call, capturing the white spaces also in the RegExp.
function camelize(str) {
return str.replace(/(?:^\w|[A-Z]|\b\w|\s+)/g, function(match, index) {
if (+match === 0) return ""; // or if (/\s+/.test(match)) for white spaces
return index === 0 ? match.toLowerCase() : match.toUpperCase();
});
}
If anyone is using lodash, there is a _.camelCase() function.
_.camelCase('Foo Bar');
// → 'fooBar'
_.camelCase('--foo-bar--');
// → 'fooBar'
_.camelCase('__FOO_BAR__');
// → 'fooBar'
To get camelCase
ES5
var camalize = function camalize(str) {
return str.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, function(match, chr)
{
return chr.toUpperCase();
});
}
ES6
var camalize = function camalize(str) {
return str.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (m, chr) => chr.toUpperCase());
}
> To get ***C**amel**S**entence**C**ase* or ***P**ascal**C**ase*
var camelSentence = function camelSentence(str) {
return (" " + str).toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, function(match, chr)
{
return chr.toUpperCase();
});
}
Note :
For those language with accents. Do include À-ÖØ-öø-ÿ with the regex as following
.replace(/[^a-zA-ZÀ-ÖØ-öø-ÿ0-9]+(.)/g This is only for one language. For another language, you have to search and find
I just ended up doing this:
String.prototype.toCamelCase = function(str) {
return str
.replace(/\s(.)/g, function($1) { return $1.toUpperCase(); })
.replace(/\s/g, '')
.replace(/^(.)/, function($1) { return $1.toLowerCase(); });
}
I was trying to avoid chaining together multiple replace statements. Something where I'd have $1, $2, $3 in my function. But that type of grouping is hard to understand, and your mention about cross browser problems is something I never thought about as well.
You can use this solution :
function toCamelCase(str){
return str.split(' ').map(function(word,index){
// If it is the first word make sure to lowercase all the chars.
if(index == 0){
return word.toLowerCase();
}
// If it is not the first word only upper case the first char and lowercase the rest.
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
}).join('');
}
In Scott’s specific case I’d go with something like:
String.prototype.toCamelCase = function() {
return this.replace(/^([A-Z])|\s(\w)/g, function(match, p1, p2, offset) {
if (p2) return p2.toUpperCase();
return p1.toLowerCase();
});
};
'EquipmentClass name'.toCamelCase() // -> equipmentClassName
'Equipment className'.toCamelCase() // -> equipmentClassName
'equipment class name'.toCamelCase() // -> equipmentClassName
'Equipment Class Name'.toCamelCase() // -> equipmentClassName
The regex will match the first character if it starts with a capital letter, and any alphabetic character following a space, i.e. 2 or 3 times in the specified strings.
By spicing up the regex to /^([A-Z])|[\s-_](\w)/g it will also camelize hyphen and underscore type names.
'hyphen-name-format'.toCamelCase() // -> hyphenNameFormat
'underscore_name_format'.toCamelCase() // -> underscoreNameFormat
Reliable, high-performance example:
function camelize(text) {
const a = text.toLowerCase()
.replace(/[-_\s.]+(.)?/g, (_, c) => c ? c.toUpperCase() : '');
return a.substring(0, 1).toLowerCase() + a.substring(1);
}
Case-changing characters:
hyphen -
underscore _
period .
space
function toCamelCase(str) {
// Lower cases the string
return str.toLowerCase()
// Replaces any - or _ characters with a space
.replace( /[-_]+/g, ' ')
// Removes any non alphanumeric characters
.replace( /[^\w\s]/g, '')
// Uppercases the first character in each group immediately following a space
// (delimited by spaces)
.replace( / (.)/g, function($1) { return $1.toUpperCase(); })
// Removes spaces
.replace( / /g, '' );
}
I was trying to find a JavaScript function to camelCase a string, and wanted to make sure special characters would be removed (and I had trouble understanding what some of the answers above were doing). This is based on c c young's answer, with added comments and the removal of $peci&l characters.
If regexp isn't required, you might want to look at following code I made a long time ago for Twinkle:
String.prototype.toUpperCaseFirstChar = function() {
return this.substr( 0, 1 ).toUpperCase() + this.substr( 1 );
}
String.prototype.toLowerCaseFirstChar = function() {
return this.substr( 0, 1 ).toLowerCase() + this.substr( 1 );
}
String.prototype.toUpperCaseEachWord = function( delim ) {
delim = delim ? delim : ' ';
return this.split( delim ).map( function(v) { return v.toUpperCaseFirstChar() } ).join( delim );
}
String.prototype.toLowerCaseEachWord = function( delim ) {
delim = delim ? delim : ' ';
return this.split( delim ).map( function(v) { return v.toLowerCaseFirstChar() } ).join( delim );
}
I haven't made any performance tests, and regexp versions might or might not be faster.
My ES6 approach:
const camelCase = str => {
let string = str.toLowerCase().replace(/[^A-Za-z0-9]/g, ' ').split(' ')
.reduce((result, word) => result + capitalize(word.toLowerCase()))
return string.charAt(0).toLowerCase() + string.slice(1)
}
const capitalize = str => str.charAt(0).toUpperCase() + str.toLowerCase().slice(1)
let baz = 'foo bar'
let camel = camelCase(baz)
console.log(camel) // "fooBar"
camelCase('foo bar') // "fooBar"
camelCase('FOO BAR') // "fooBar"
camelCase('x nN foo bar') // "xNnFooBar"
camelCase('!--foo-¿?-bar--121-**%') // "fooBar121"
This function by pass cammelcase such these tests
Foo Bar
--foo-bar--
__FOO_BAR__-
foo123Bar
foo_Bar
function toCamelCase(str)
{
var arr= str.match(/[a-z]+|\d+/gi);
return arr.map((m,i)=>{
let low = m.toLowerCase();
if (i!=0){
low = low.split('').map((s,k)=>k==0?s.toUpperCase():s).join``
}
return low;
}).join``;
}
console.log(toCamelCase('Foo Bar'));
console.log(toCamelCase('--foo-bar--'));
console.log(toCamelCase('__FOO_BAR__-'));
console.log(toCamelCase('foo123Bar'));
console.log(toCamelCase('foo_Bar'));
console.log(toCamelCase('EquipmentClass name'));
console.log(toCamelCase('Equipment className'));
console.log(toCamelCase('equipment class name'));
console.log(toCamelCase('Equipment Class Name'));
Here is a one liner doing the work:
const camelCaseIt = string => string.toLowerCase().trim().split(/[.\-_\s]/g).reduce((string, word) => string + word[0].toUpperCase() + word.slice(1));
It splits the lower-cased string based on the list of characters provided in the RegExp [.\-_\s] (add more inside the []!) and returns a word array . Then, it reduces the array of strings to one concatenated string of words with uppercased first letters. Because the reduce has no initial value, it will start uppercasing first letters starting with the second word.
If you want PascalCase, just add an initial empty string ,'') to the reduce method.
The top answer is terse but it doesn't handle all edge cases. For anyone needing a more robust utility, without any external dependencies:
function camelCase(str) {
return (str.slice(0, 1).toLowerCase() + str.slice(1))
.replace(/([-_ ]){1,}/g, ' ')
.split(/[-_ ]/)
.reduce((cur, acc) => {
return cur + acc[0].toUpperCase() + acc.substring(1);
});
}
function sepCase(str, sep = '-') {
return str
.replace(/[A-Z]/g, (letter, index) => {
const lcLet = letter.toLowerCase();
return index ? sep + lcLet : lcLet;
})
.replace(/([-_ ]){1,}/g, sep)
}
// All will return 'fooBarBaz'
console.log(camelCase('foo_bar_baz'))
console.log(camelCase('foo-bar-baz'))
console.log(camelCase('foo_bar--baz'))
console.log(camelCase('FooBar Baz'))
console.log(camelCase('FooBarBaz'))
console.log(camelCase('fooBarBaz'))
// All will return 'foo-bar-baz'
console.log(sepCase('fooBarBaz'));
console.log(sepCase('FooBarBaz'));
console.log(sepCase('foo-bar-baz'));
console.log(sepCase('foo_bar_baz'));
console.log(sepCase('foo___ bar -baz'));
console.log(sepCase('foo-bar-baz'));
// All will return 'foo__bar__baz'
console.log(sepCase('fooBarBaz', '__'));
console.log(sepCase('foo-bar-baz', '__'));
Demo here: https://codesandbox.io/embed/admiring-field-dnm4r?fontsize=14&hidenavigation=1&theme=dark
lodash can do the trick sure and well:
var _ = require('lodash');
var result = _.camelCase('toto-ce héros')
// result now contains "totoCeHeros"
Although lodash may be a "big" library (~4kB), it contains a lot of functions that you'd normally use a snippet for, or build yourself.
return "hello world".toLowerCase().replace(/(?:(^.)|(\s+.))/g, function(match) {
return match.charAt(match.length-1).toUpperCase();
}); // HelloWorld
Because this question needed yet another answer...
I tried several of the previous solutions, and all of them had one flaw or another. Some didn't remove punctuation; some didn't handle cases with numbers; some didn't handle multiple punctuations in a row.
None of them handled a string like a1 2b. There's no explicitly defined convention for this case, but some other stackoverflow questions suggested separating the numbers with an underscore.
I doubt this is the most performant answer (three regex passes through the string, rather than one or two), but it passes all the tests I can think of. To be honest, though, I really can't imagine a case where you're doing so many camel-case conversions that performance would matter.
(I added this as an npm package. It also includes an optional boolean parameter to return Pascal Case instead of Camel Case.)
const underscoreRegex = /(?:[^\w\s]|_)+/g,
sandwichNumberRegex = /(\d)\s+(?=\d)/g,
camelCaseRegex = /(?:^\s*\w|\b\w|\W+)/g;
String.prototype.toCamelCase = function() {
if (/^\s*_[\s_]*$/g.test(this)) {
return '_';
}
return this.replace(underscoreRegex, ' ')
.replace(sandwichNumberRegex, '$1_')
.replace(camelCaseRegex, function(match, index) {
if (/^\W+$/.test(match)) {
return '';
}
return index == 0 ? match.trimLeft().toLowerCase() : match.toUpperCase();
});
}
Test cases (Jest)
test('Basic strings', () => {
expect(''.toCamelCase()).toBe('');
expect('A B C'.toCamelCase()).toBe('aBC');
expect('aB c'.toCamelCase()).toBe('aBC');
expect('abc def'.toCamelCase()).toBe('abcDef');
expect('abc__ _ _def'.toCamelCase()).toBe('abcDef');
expect('abc__ _ d_ e _ _fg'.toCamelCase()).toBe('abcDEFg');
});
test('Basic strings with punctuation', () => {
expect(`a'b--d -- f.h`.toCamelCase()).toBe('aBDFH');
expect(`...a...def`.toCamelCase()).toBe('aDef');
});
test('Strings with numbers', () => {
expect('12 3 4 5'.toCamelCase()).toBe('12_3_4_5');
expect('12 3 abc'.toCamelCase()).toBe('12_3Abc');
expect('ab2c'.toCamelCase()).toBe('ab2c');
expect('1abc'.toCamelCase()).toBe('1abc');
expect('1Abc'.toCamelCase()).toBe('1Abc');
expect('abc 2def'.toCamelCase()).toBe('abc2def');
expect('abc-2def'.toCamelCase()).toBe('abc2def');
expect('abc_2def'.toCamelCase()).toBe('abc2def');
expect('abc1_2def'.toCamelCase()).toBe('abc1_2def');
expect('abc1 2def'.toCamelCase()).toBe('abc1_2def');
expect('abc1 2 3def'.toCamelCase()).toBe('abc1_2_3def');
});
test('Oddball cases', () => {
expect('_'.toCamelCase()).toBe('_');
expect('__'.toCamelCase()).toBe('_');
expect('_ _'.toCamelCase()).toBe('_');
expect('\t_ _\n'.toCamelCase()).toBe('_');
expect('_a_'.toCamelCase()).toBe('a');
expect('\''.toCamelCase()).toBe('');
expect(`\tab\tcd`.toCamelCase()).toBe('abCd');
expect(`
ab\tcd\r
-_
|'ef`.toCamelCase()).toBe(`abCdEf`);
});
To effectively create a function that converts the casing of a string to camel-case, the function will also need to convert each string to lower-case first, before transforming the casing of the first character of non-first strings to an uppercase letter.
My example string is:
"text That I WaNt to make cAMEL case"
Many other solutions provided to this question return this:
"textThatIWaNtToMakeCAMELCase"
What I believe should be the expected, desired output would be this though, where all the mid-string uppercase characters are first transformed to be lowercase:
"textThatIWanrtToMakeCamelCase"
This can be done WITHOUT using any replace() method calls, by utilizing the String.prototype.split(), Array.prototype.map(), and Array.prototype.join() methods:
≤ ES5 Version
function makeCamelCase(str) {
return str
.split(' ')
.map((e,i) => i
? e.charAt(0).toUpperCase() + e.slice(1).toLowerCase()
: e.toLowerCase()
)
.join('')
}
makeCamelCase("text That I WaNt to make cAMEL case")
// -> "textThatIWanrtToMakeCamelCase" ✅
I'll break down what each line does, and then provide the same solution in two other formats— ES6 and as a String.prototype method, though I'd advise against extending built-in JavaScript prototypes directly like this.
Explainer
function makeCamelCase(str) {
return str
// split string into array of different words by splitting at spaces
.split(' ')
// map array of words into two different cases, one for the first word (`i == false`) and one for all other words in the array (where `i == true`). `i` is a parameter that denotes the current index of the array item being evaluated. Because indexes start at `0` and `0` is a "falsy" value, we can use the false/else case of this ternary expression to match the first string where `i === 0`.
.map((e,i) => i
// for all non-first words, use a capitalized form of the first character + the lowercase version of the rest of the word (excluding the first character using the slice() method)
? e.charAt(0).toUpperCase() + e.slice(1).toLowerCase()
// for the first word, we convert the entire word to lowercase
: e.toLowerCase()
)
// finally, we join the different strings back together into a single string without spaces, our camel-cased string
.join('')
}
makeCamelCase("text That I WaNt to make cAMEL case")
// -> "textThatIWanrtToMakeCamelCase" ✅
Condensed ES6+ (One-Liner) Version
const makeCamelCase = str => str.split(' ').map((e,i) => i ? e.charAt(0).toUpperCase() + e.slice(1).toLowerCase() : e.toLowerCase()).join('')
makeCamelCase("text That I WaNt to make cAMEL case")
// -> "textThatIWanrtToMakeCamelCase" ✅
String.prototype method version
String.prototype.toCamelCase = function() {
return this
.split(' ')
.map((e,i) => i
? e.charAt(0).toUpperCase() + e.slice(1).toLowerCase()
: e.toLowerCase()
)
.join('')
}
"text That I WaNt to make cAMEL case".toCamelCase()
// -> "textThatIWanrtToMakeCamelCase" ✅
little modified Scott's answer:
toCamelCase = (string) ->
string
.replace /[\s|_|-](.)/g, ($1) -> $1.toUpperCase()
.replace /[\s|_|-]/g, ''
.replace /^(.)/, ($1) -> $1.toLowerCase()
now it replaces '-' and '_' too.
All 14 permutations below produce the same result of "equipmentClassName".
String.prototype.toCamelCase = function() {
return this.replace(/[^a-z ]/ig, '') // Replace everything but letters and spaces.
.replace(/(?:^\w|[A-Z]|\b\w|\s+)/g, // Find non-words, uppercase letters, leading-word letters, and multiple spaces.
function(match, index) {
return +match === 0 ? "" : match[index === 0 ? 'toLowerCase' : 'toUpperCase']();
});
}
String.toCamelCase = function(str) {
return str.toCamelCase();
}
var testCases = [
"equipment class name",
"equipment class Name",
"equipment Class name",
"equipment Class Name",
"Equipment class name",
"Equipment class Name",
"Equipment Class name",
"Equipment Class Name",
"equipment className",
"equipment ClassName",
"Equipment ClassName",
"equipmentClass name",
"equipmentClass Name",
"EquipmentClass Name"
];
for (var i = 0; i < testCases.length; i++) {
console.log(testCases[i].toCamelCase());
};
you can use this solution:
String.prototype.toCamelCase = function(){
return this.replace(/\s(\w)/ig, function(all, letter){return letter.toUpperCase();})
.replace(/(^\w)/, function($1){return $1.toLowerCase()});
};
console.log('Equipment className'.toCamelCase());
Here's my suggestion:
function toCamelCase(string) {
return `${string}`
.replace(new RegExp(/[-_]+/, 'g'), ' ')
.replace(new RegExp(/[^\w\s]/, 'g'), '')
.replace(
new RegExp(/\s+(.)(\w+)/, 'g'),
($1, $2, $3) => `${$2.toUpperCase() + $3.toLowerCase()}`
)
.replace(new RegExp(/\s/, 'g'), '')
.replace(new RegExp(/\w/), s => s.toLowerCase());
}
or
String.prototype.toCamelCase = function() {
return this
.replace(new RegExp(/[-_]+/, 'g'), ' ')
.replace(new RegExp(/[^\w\s]/, 'g'), '')
.replace(
new RegExp(/\s+(.)(\w+)/, 'g'),
($1, $2, $3) => `${$2.toUpperCase() + $3.toLowerCase()}`
)
.replace(new RegExp(/\s/, 'g'), '')
.replace(new RegExp(/\w/), s => s.toLowerCase());
};
Test cases:
describe('String to camel case', function() {
it('should return a camel cased string', function() {
chai.assert.equal(toCamelCase('foo bar'), 'fooBar');
chai.assert.equal(toCamelCase('Foo Bar'), 'fooBar');
chai.assert.equal(toCamelCase('fooBar'), 'fooBar');
chai.assert.equal(toCamelCase('FooBar'), 'fooBar');
chai.assert.equal(toCamelCase('--foo-bar--'), 'fooBar');
chai.assert.equal(toCamelCase('__FOO_BAR__'), 'fooBar');
chai.assert.equal(toCamelCase('!--foo-¿?-bar--121-**%'), 'fooBar121');
});
});
following #Scott's readable approach, a little bit of fine tuning
// convert any string to camelCase
var toCamelCase = function(str) {
return str.toLowerCase()
.replace( /['"]/g, '' )
.replace( /\W+/g, ' ' )
.replace( / (.)/g, function($1) { return $1.toUpperCase(); })
.replace( / /g, '' );
}
There is my solution:
const toCamelWord = (word, idx) =>
idx === 0 ?
word.toLowerCase() :
word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
const toCamelCase = text =>
text
.split(/[_-\s]+/)
.map(toCamelWord)
.join("");
console.log(toCamelCase('User ID'))
This method seems to outperform most answers on here, it's a little bit hacky though, no replaces, no regex, simply building up a new string that's camelCase.
String.prototype.camelCase = function(){
var newString = '';
var lastEditedIndex;
for (var i = 0; i < this.length; i++){
if(this[i] == ' ' || this[i] == '-' || this[i] == '_'){
newString += this[i+1].toUpperCase();
lastEditedIndex = i+1;
}
else if(lastEditedIndex !== i) newString += this[i].toLowerCase();
}
return newString;
}
This builds on the answer by CMS by removing any non-alphabetic characters including underscores, which \w does not remove.
function toLowerCamelCase(str) {
return str.replace(/[^A-Za-z0-9]/g, ' ').replace(/^\w|[A-Z]|\b\w|\s+/g, function (match, index) {
if (+match === 0 || match === '-' || match === '.' ) {
return ""; // or if (/\s+/.test(match)) for white spaces
}
return index === 0 ? match.toLowerCase() : match.toUpperCase();
});
}
toLowerCamelCase("EquipmentClass name");
toLowerCamelCase("Equipment className");
toLowerCamelCase("equipment class name");
toLowerCamelCase("Equipment Class Name");
toLowerCamelCase("Equipment-Class-Name");
toLowerCamelCase("Equipment_Class_Name");
toLowerCamelCase("Equipment.Class.Name");
toLowerCamelCase("Equipment/Class/Name");
// All output e
Upper camel case ("TestString") to lower camel case ("testString") without using regex (let's face it, regex is evil):
'TestString'.split('').reduce((t, v, k) => t + (k === 0 ? v.toLowerCase() : v), '');
I ended up crafting a slightly more aggressive solution:
function toCamelCase(str) {
const [first, ...acc] = str.replace(/[^\w\d]/g, ' ').split(/\s+/);
return first.toLowerCase() + acc.map(x => x.charAt(0).toUpperCase()
+ x.slice(1).toLowerCase()).join('');
}
This one, above, will remove all non-alphanumeric characters and lowercase parts of words that would otherwise remain uppercased, e.g.
Size (comparative) => sizeComparative
GDP (official exchange rate) => gdpOfficialExchangeRate
hello => hello
function convertStringToCamelCase(str){
return str.split(' ').map(function(item, index){
return index !== 0
? item.charAt(0).toUpperCase() + item.substr(1)
: item.charAt(0).toLowerCase() + item.substr(1);
}).join('');
}
I know this is an old answer, but this handles both whitespace and _ (lodash)
function toCamelCase(s){
return s
.replace(/_/g, " ")
.replace(/\s(.)/g, function($1) { return $1.toUpperCase(); })
.replace(/\s/g, '')
.replace(/^(.)/, function($1) { return $1.toLowerCase(); });
}
console.log(toCamelCase("Hello world");
console.log(toCamelCase("Hello_world");
// Both print "helloWorld"
const toCamelCase = str =>
str
.replace(/[^a-zA-Z0-9]+(.)/g, (m, chr) => chr.toUpperCase())
.replace(/^\w/, c => c.toLowerCase());

Categories