Search code examples
javascriptregexcamelcasing

Regular rxpression to convert a camel case string into kebab case


function hyphenate(str) {

  var replace = "-";
  str = str.toLowerCase().replace(/[\s_\b]/g, replace);

  console.log(str);
  return str;
}

hyphenate("This Is Hyphenate"); // this-is-hyphenate
hyphenate("camelCaseString");   // camel-case-string

I am trying to get my code to produce the results of the second function call, but have not identified a pattern that can do this. Any assistance would be greatly appreciated.


Solution

  • Note that \b in your [\s_\b] means a backspace character. Not sure you really need this.

    Updated answer using the lookbehind feature introduced in ECMAScript 2018:

    const re = /[\W_]+|(?<=[a-z0-9])(?=[A-Z])/g;
    const strs = ['camelCaseString','This      Is Hyphenate','This_Should_Hyphenate', '09Report'];
    strs.forEach(str => 
      console.log( str.replace(re, "-").toLowerCase() )
    );

    The [\W_]+|(?<=[a-z0-9])(?=[A-Z]) regex will match

    • [\W_]+ - any 1+ non-word and _ chars
    • | - or
    • (?<=[a-z0-9])(?=[A-Z]) - a location between a lowercase ASCII letter/digit and an uppercase ASCII letter.

    Old answer

    I'd use a bit different logic: add a hyphen before each capital letter inside a word, and then replace and turn lowercase:

    var re = /[\s_]+|([a-z0-9])(?=[A-Z])/g; 
    var str = 'camelCaseString<br/>This      Is Hyphenate<br/>This_Should_Hyphenate';
    var result = str.replace(re, "$1-").toLowerCase();
    document.body.innerHTML += result;

    Explanation:

    • [\s_]+ - one or more whitespaces or underscores
    • | - or...
    • ([a-z0-9]) - (Group 1) a lowercase letter or digit (since \B would not let us match an uppercase letter after _, add A-Z if you want to add - before each uppercase letter)
    • (?=[A-Z]) - a test for an uppercase ASCII letter (that is not consumed since it (?=[A-Z]) is a lookahead, a zero width assertion).