diff --git a/src/lib/forms-shared.ts b/src/lib/forms-shared.ts index 930bd46..f123154 100644 --- a/src/lib/forms-shared.ts +++ b/src/lib/forms-shared.ts @@ -151,11 +151,18 @@ export function applyCase(value: string, modifier?: string | null): string { return value.toLowerCase().replace(/\b([a-z\u00C0-\u024F])/g, (c) => c.toUpperCase()); case "sentence": case "capitalize": { - // Lowercase the whole string, then capitalize the first letter of each sentence. + // Lowercase, then uppercase the first letter and the first letter + // following any sentence terminator. Skips leading non-letters + // (numbers, punctuation, whitespace) so "123 main st" -> "123 Main st" + // is unchanged but "main st." -> "Main st." works. const lower = value.toLowerCase(); - return lower.replace(/(^\s*[a-z\u00C0-\u024F])|([.!?]\s+[a-z\u00C0-\u024F])/g, (s) => - s.toUpperCase(), + // First letter anywhere at the start of the string (after non-letters). + let result = lower.replace(/^[^a-z\u00C0-\u024F]*[a-z\u00C0-\u024F]/, (s) => + s.slice(0, -1) + s.slice(-1).toUpperCase(), ); + // First letter after each sentence terminator. + result = result.replace(/([.!?]\s+)([a-z\u00C0-\u024F])/g, (_m, p, c) => p + c.toUpperCase()); + return result; } default: return value;