Daniel Arnost
Daniel Arnost

Reputation: 87

hyphens in Regular Expressions/ javascript camelCase function

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

Answers (2)

Dmitry Egorov
Dmitry Egorov

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

David784
David784

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:

  • change order of asssertions in phrase.replace regexp. We want a space-word combo to take precedence over a capitalized match.
  • add a capturing group to the space, so that we can know better if the capture follows a space
  • change the boolean expression: we want it to be lower case if:
    1. it's the first character (index===0)
    2. OR there isn't a space match (this would be an [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

Related Questions