Skip to content
Advertisement

Convert pair of regex replacements with single replacement

I want to split a string on the first capital letter in a group.

For example, FooBARBaz should become Foo BAR Baz.

I’ve come up with:

str.replace(/[A-Z][a-z]+/g, ' $&')
    .replace(/[A-Z]+/g, ' $&')
    .replace(/s+/g, ' ')
    .trim();

Can anyone suggest a cleaner solution?

Advertisement

Answer

A simple regex like /([A-Z][a-z]+)/g already does it … the trick is the capture group which gets preserved when being used with the split method. Thus one just needs to go for one group pattern (a single uppercase letter followed by at least one lower case letter) and does get the rest (a valid all uppercase letter group) for free. And since the split array in addition contains empty string values one needs to run an extra filter task.

console.log(
  'just split ...n',
  '"FooBARBazBizBuzBOOOOZBozzzBarFOOBARBazbizBUZBoooozBOZZZBar" =>',

  'FooBARBazBizBuzBOOOOZBozzzBarFOOBARBazbizBUZBoooozBOZZZBar'
    .split(/([A-Z][a-z]+)/g)
);
console.log(
  'split and filter ...n',
  '"FooBARBazBizBuzBOOOOZBozzzBarFOOBARBazbizBUZBoooozBOZZZBar" =>',

  'FooBARBazBizBuzBOOOOZBozzzBarFOOBARBazbizBUZBoooozBOZZZBar'
    .split(/([A-Z][a-z]+)/g)
    .filter(val => val !== '')
);
console.log(
  'split, filter and join ...n',
  '"FooBARBazBizBuzBOOOOZBozzzBarFOOBARBazbizBUZBoooozBOZZZBar" =>n',

  'FooBARBazBizBuzBOOOOZBozzzBarFOOBARBazbizBUZBoooozBOZZZBar'
    .split(/([A-Z][a-z]+)/g)
    .filter(val => val !== '')
    .join(' ')
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement