3

I am trying to Capitalize the first letter of each word in a string. I found similar questions online but none seem to answer my question of ignoring Contractions like can't, won't, wasn't.

This snippet of code works but it also capitalizes the letter after the apostrophe in the contraction.

var str = str.replace(/\b\w/g, w => w.toUpperCase())

If the string contains a contraction like can't or won't it will output Can'T or Won'T.

Is there a way to ignore apostrophes that are in the middle of a word? I still want to capitalize words that are separated by other punctuation. For example:

  • this_is_an_example -> This_Is_An_Example
  • this/is/an/example -> This/Is/An/Example
  • this,is,an,example -> This,Is,An,Example
Shayne
  • 33
  • 3

3 Answers3

1

You can use

const texts = ["this_can't_be_an_example", 'this/is/an/example', 'this,is,an,example']
for (const text of texts) {
  console.log(text, '=>', text.replace(/([\W_]|^)(\w)(?<!\w'\w)/g, (_, x,y) => `${x}${y.toUpperCase()}` ))
}

See the regex demo. Details:

  • ([\W_]|^) - Group 1 (x): a non-alphanumeric char or start of string
  • (\w) - Group 2 (y): a word char
  • (?<!\w'\w) - a negative lookbehind that makes sure the Group 2 value is not preceded with a word char and a '.
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
0

You can use a negative lookbehind to make sure that there isn't an apostrophy before the word boundary. (?:\b|(?<=_)) checks for a word boundary or a underscore before the word.

const examples = [
  "can't",
  "this-is-an-example",
  "this.is.an.example",
  "this/is/an/example",
  "this_is_an_example",
  "this,is,an,example",
];

examples.forEach(example => {
  console.log(example.replace(/(?<!')(?:\b|(?<=_))\w/g, w => w.toUpperCase()));
});
lusc
  • 1,206
  • 1
  • 10
  • 19
0

This RegExp detect

  • First symbol
  • Underline
  • Space
  • / symbol
  • Comma
  • Apostrophe

Just add need symbols in list with | separator

str.replace(/((^|_| |\/|,|')\w)/g, w => w.toUpperCase());
EzioMercer
  • 1,502
  • 2
  • 7
  • 23