Reputation: 87
The Function should take a string as an argument and camel case it. I am having trouble with hyphens while using regex and string.replace() method.
camelCase('state-of-the-art') should return 'state-of-the-art' camelCase("Don't worry kyoko") should return "dontWorryKyoko"
The following works for both cases, but I want to make it DRY, take out the hyphens if clause and include the hyphen case in .replace() and it's call-back.
function camelCase(phrase) {
let re = /[a-z]+/i;
let hyphens = /[-+]/g
if(typeof phrase !== 'string' || !phrase.match(re) || !phrase || phrase === null){
return "Please enter a valid string.";
} else if (phrase.match(hyphens)){
return phrase.toLocaleLowerCase();
}else{
return phrase.replace(/(?:^\w+|[A-Z]|\s+\w)/g, function(letter, index) {
return index == 0 ? letter.toLowerCase() : letter.toUpperCase();
}).replace(/\W+/g, '');
}
}
console.log(camelCase('state-of-the-art')) // 'state-of-the-art'
console.log(camelCase("Don't look back")) // dontLookBack
Can we make the hyphen case work without the hyphens if clause?
Also I feel like camelCase("don't lOOk_BaCK")
should lowercase letters with index > 0 but it doesn't seem to be doing that in the console.
Anyone wanna help with this? Thanx
Upvotes: 0
Views: 210
Reputation: 9650
To cope with the hyphen issue you may consider -
a part of alphanumeric class by using [\w-]
or [^\w-]
where appropriate.
To lowercase all non-first letters I suggest to match all words with (\S)(\S*)
uppercasing $1
(where appropriate) and lowercasing $2
:
function camelCase(phrase) {
return phrase.replace(/[^\w-]*(\S)(\S+)/g, function(_, first, rest, index) {
return (index ? first.toUpperCase() : first.toLowerCase())
+ rest.toLowerCase();
}).replace(/[^\w-]+/g, "");
}
console.log(camelCase("state-of-the-art"));
console.log(camelCase("-state-of-the-art"));
console.log(camelCase("Don't look back"));
console.log(camelCase("don't lOOk_BaCK"));
console.log(camelCase("???don't lOOk_BaCK"));
Upvotes: 1
Reputation: 7464
You can make the hyphens work by adding a negative lookahead assertion .replace(/(?!-)\W+/g, '');
. This would tell it to replace all non-word characters, except a -
dash character.
Regarding your lower-casing problem: your only criteria right now to decide the case is if it appears at the beginning of the string. Otherwise you're UPPER casing everything (including the upper case matches). This is also a pretty easy fix. Here's the whole thing:
function camelCase(phrase) {
let re = /[a-z]+/i;
if (typeof phrase !== 'string' || !phrase.match(re) || !phrase || phrase === null) {
return "Please enter a valid string.";
} else {
return phrase.replace(/(?:^\w+|(\s+)\w)|[A-Z]/g, function (letter, sp, index) {
console.log(letter, sp, index);
return (index == 0 || sp === undefined) ? letter.toLowerCase() : letter.toUpperCase();
}).replace(/(?!-)\W+/g, '');
}
}
Explanation of the changes:
phrase.replace
regexp. We want a space-word combo to take precedence over a capitalized match.index===0
)[A-Z]
match, without a preceding space)Also just as an aside, you don't appear to be camel-casing on a _
underscore character, only on spaces. Is this intentional? I've never seen a camel-case routine that didn't convert snake-case (underscore).
Upvotes: 0