"""Port Python de `normalizeText` (`apps/api/src/lib/recipe-matching/tech-step-matcher.ts`). Doit rester bit-pour-bit équivalent à sa contrepartie TypeScript — c'est ce qui garantit qu'un synonyme matché ici tombe exactement sur les mêmes positions caractère que ce que `apps/api` attendait de node-nlp (voir `LocalePipeline`'s `diacritics_normalizer`, qui applique cette fonction aux patterns *et* au texte cible pour les faire matcher identiquement). TypeScript original : const COMBINING_DIACRITICS_PATTERN = /\\p{Diacritic}/gu; export function normalizeText(text: string): string { return text.normalize("NFD").replace(COMBINING_DIACRITICS_PATTERN, "").toLowerCase(); } `unicodedata.combining(ch) != 0` (catégories Unicode Mn/Mc, la classe de combinaison canonique) est l'idiome Python standard pour "strip accents after NFD" — légèrement plus étroit que `\\p{Diacritic}` en théorie (qui couvre aussi quelques diacritiques autonomes hors caractères combinants), mais strictement équivalent pour tout caractère latin accentué usuel (français/anglais) une fois décomposé en NFD, ce qui est le seul cas réellement exercé par ce corpus. """ import unicodedata def normalize_text(text: str) -> str: """Décompose en NFD, retire les marques combinantes (accents), met en minuscule.""" decomposed = unicodedata.normalize("NFD", text) stripped = "".join(char for char in decomposed if not unicodedata.combining(char)) return stripped.lower()