Home > Blockchain >  Convert pair of regex replacements with single replacement
Convert pair of regex replacements with single replacement

Time:11-17

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?

CodePudding user response:

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; }

CodePudding user response:

You can achieve this by using this replacer function inside the String.replace() method.

Live Demo :

const str = 'FooBARBaz';

function replacer() {
  return ' '   arguments[0]   ' ';
}

console.log(str.replace(/[A-Z][a-z] /g, replacer).trim());

CodePudding user response:

You can try to match upper, followed by upper or upper not upper:

m = 'FooBARBazAB'.match(/([A-Z](?=[A-Z]|$)) |[A-Z][^A-Z]*/g)

console.log(m)

Not sure about how this is "cleaner" though.

  • Related