camel to human readable text with brackets '('

Viewed 88

I have this code where I want to change a camel case sentence to a human readable one.

It works nicely apart from when there are () - see example below. Can anyone advise on how to fix this so it would be Amazing (Stuff)

const camelToHumanReadable = (camelCase) => {
  const result = camelCase
    .replace(/([A-Z]+)/g, ' $1')
    .replace(/([A-Z][a-z])/g, ' $1')
    .replace(/ +(?= )/g, '')
    .replace(/(- )/, '-')
    .trim();

  return result.charAt(0).toUpperCase() + result.slice(1);
};

console.log(camelToHumanReadable('ItIsBeautiful')) // correct
console.log(camelToHumanReadable('Test-DashHere')) // correct
console.log(camelToHumanReadable('IAmFromTheUSA')) // correct
console.log(camelToHumanReadable('Test1')) // this should be Test 1
console.log(camelToHumanReadable('Amazing(Stuff)')) // this should be Amazing (Stuff)

2 Answers

You can try the following solution:

const camelToHumanReadable = (camelCase) => {
  const result = camelCase
    .replace(/[A-Z\d]+/g, ' $&')     // Add a space before one or more uppers or digits
    .replace(/[A-Z][a-z]/g, ' $&') // Add a space before an upper and a lower
    .replace(/( )+/g, '$1')        // Reduce spaces
    .replace(/(^|\S)- +/g, '$1-')   // Remove spaces after a non-white and -
    .replace(/([A-Za-z0-9])([({<[])/g, '$1 $2') // Add space between alnum and open punct
    .replace(/([({<[])\s+(?=[A-Za-z0-9])/g, '$1')  // Remove spaces between open punct and alnum
    .trim();

  return result.charAt(0).toUpperCase() + result.slice(1);
};
console.log(camelToHumanReadable('ItIsBeautiful'))    // It Is Beautiful
console.log(camelToHumanReadable('Active-UserHere'))  // Active-User Here
console.log(camelToHumanReadable('IAmFromTheUSA'))    // I Am From The USA
console.log(camelToHumanReadable('Test1'))            // Test 1
console.log(camelToHumanReadable('Amazing(Stuff)'))   // Amazing (Stuff)

One could also simplify the main replacement step to a more generic but strict expression like /\(*[A-Z][a-z]+\)*/g, accompanied by two minor replacements, a concatenation via /\s*-\s*/g and some sanitizing via /\s+/g together with the final trim.

A more forgiving/loose expression, in terms of handling digits, was /\(*(?:[A-Z]|(?<=\d))[a-z]+\)*/g.

const camelToHumanReadable = (camelCase) => {
  const result = camelCase
    // // forgiving/loose ... [https://regex101.com/r/LxXnR2/2]
    //.replace(/\(*(?:[A-Z]|(?<=\d))[a-z]+\)*/g, ' $& ')
    //
    // strict ... [https://regex101.com/r/LxXnR2/1]
    .replace(/\(*[A-Z][a-z]+\)*/g, ' $& ')
    .replace(/\s*-\s*/g, '-')
    .replace(/\s+/g, ' ')
    .trim();

  return result.charAt(0).toUpperCase() + result.slice(1);
};

console.log(camelToHumanReadable('ItIsBeautiful')) // It Is Beautiful
console.log(camelToHumanReadable('Test-DashHere')) // Test-Dash Here
console.log(camelToHumanReadable('iAmFromTheUSA')) // I Am From The USA
console.log(camelToHumanReadable('Test1')) // Test 1
console.log(camelToHumanReadable('amazing(Stuff)')) // Amazing (Stuff)

console.log(
  `ItIsBeautiful
  itIsBeautiful
  Active-UserHere
  Active-USERHere
  active-USERHere
  anActive-USERHere
  AnActive-USERHere
  iAmFromTheUSAAndA
  IAmFromTheUSAAndA
  IAmFromTheUSA
  amazing(Stuff-abc)AndMore
  Amazing(Stuff-abc)AndMore
  Amazing(Stuff-ABC)AndMore
  Amazing(Stuff-abc)
  Amazing(Stuff)
  Amazing(Stuff-Abc)(Stuff)
  Test13-45Test3AndUSAAnd-4-5-testTest-2-3Test`
  .split(/\n+/)
  .map(camelToHumanReadable)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

Related