I currently want to make the first letter of a city name uppercase; but since in my country we have a lot of cities with a multiple words composed name (eg. New York), i am currently using this regex:
/\w\S*/g
so I am using this function
function capitalizeWords(myString) {
return myString.replace(/\w\S*/g, w => w.replace(/^\w/, c => c.toUpperCase()))
}
so I can change new york
in New York
.
But now I have a small issue, I have some cities like
sauze d'oulx
and I need to convert it to Sauze d'Oulx
, excluding the d
, or in any case the first character before the '
symbol.
What is the trick to exclude one char before a known one?
CodePudding user response:
You can define all your exceptions as alternatives before matching and capturing your expected match:
const texts = ["new york", "sauze d'oulx"];
const capitalizeWords = (myString) =>
myString.replace(/\bd['’]|(\w)(\S*)/g, (m, g, h) => g ? g.toUpperCase() h : m);
for (const text of texts) {
console.log(text, '->', capitalizeWords(text));
}
The \bd['’]|(\w)(\S*)
regex matches
\bd['’]
- ad'
ord’
after a non-word char or at the start of string|
- or(\w)(\S*)
- a word char captured into Group 1 (g
in the code above) and then zero or more non-whitespaces into Group 2 (h
in the code above).
The (m, g, h) => g ? g.toUpperCase() h : m
replacement means that the replacement is the match itself if Group 1 did not match, else, the char matched with \w
is capitalized.
Extending with di
preposition:
const texts = ["new york", "sauze d'oulx", "bagno di romagna"];
const capitalizeWords = (myString) =>
myString.replace(/\bd(?:['’]|i\b)|(\w)(\S*)/g, (m, g, h) => g ? g.toUpperCase() h : m);
for (const text of texts) {
console.log(text, '->', capitalizeWords(text));
}