From 436a52283e7ea71abb35a63774f5942b53963406 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 11 May 2026 11:08:02 -0700 Subject: [PATCH] fix(providers): add missing regex capture group in article gender contractions The lexical substitution pipeline's fixArticleGender function had 4 regex replacement patterns that referenced $3 but only defined 2 capture groups. The noun between the article and word boundary was not captured, causing the replacement string to either emit a literal "$3" into output text or drop the noun entirely. Wrap the noun pattern in a capture group so all 3 backreferences ($1=boundary, $2=noun, $3=trailing boundary) resolve correctly. Co-Authored-By: Claude Opus 4.7 --- packages/providers/src/lexical-substitution.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/providers/src/lexical-substitution.ts b/packages/providers/src/lexical-substitution.ts index 44e029f..92557e4 100644 --- a/packages/providers/src/lexical-substitution.ts +++ b/packages/providers/src/lexical-substitution.ts @@ -150,20 +150,20 @@ function fixArticleGender(text: string, oldNoun: string, newNoun: string): strin if (newGender === "m") { text = text.replace( - new RegExp(`(^|[^\\p{L}\\p{N}])de\\s+la\\s+${nounLower}([^\\p{L}\\p{N}]|$)`, "giu"), + new RegExp(`(^|[^\\p{L}\\p{N}])de\\s+la\\s+(${nounLower})([^\\p{L}\\p{N}]|$)`, "giu"), "$1del $2$3" ); text = text.replace( - new RegExp(`(^|[^\\p{L}\\p{N}])a\\s+la\\s+${nounLower}([^\\p{L}\\p{N}]|$)`, "giu"), + new RegExp(`(^|[^\\p{L}\\p{N}])a\\s+la\\s+(${nounLower})([^\\p{L}\\p{N}]|$)`, "giu"), "$1al $2$3" ); } else { text = text.replace( - new RegExp(`(^|[^\\p{L}\\p{N}])del\\s+${nounLower}([^\\p{L}\\p{N}]|$)`, "giu"), + new RegExp(`(^|[^\\p{L}\\p{N}])del\\s+(${nounLower})([^\\p{L}\\p{N}]|$)`, "giu"), "$1de la $2$3" ); text = text.replace( - new RegExp(`(^|[^\\p{L}\\p{N}])al\\s+${nounLower}([^\\p{L}\\p{N}]|$)`, "giu"), + new RegExp(`(^|[^\\p{L}\\p{N}])al\\s+(${nounLower})([^\\p{L}\\p{N}]|$)`, "giu"), "$1a la $2$3" ); }