ucfirst(strtolower($name)) casse les noms, et cela se mesure
Tout pipeline de traitement de noms finit par rencontrer une source qui crie. Les registres nationaux stockent les noms en majuscules — MCKENZIE, O'BRIEN, NGUYEN VAN NAM — parce que les systèmes dont ils sont issus ne connaissaient pas les minuscules. Quelque part entre ce fichier et votre interface, quelqu'un doit décider où vont les majuscules.
Le one-liner auquel tout le monde a recours est celui-ci :
$name = ucfirst(strtolower($name)); // PHP
name = name.title() // Python — same class of bug, different shape
name[0].toUpperCase() + name.slice(1).toLowerCase() // JS
Il produit Mckenzie, O'brien, Van Der Berg et Tôn-nữ. Les quatre sont faux. Non pas « inhabituels » — faux, au sens où aucun registre, aucun guide de style et aucun porteur ne les écrit ainsi.
Nous le savons parce que nous en avons livré deux. Cette page explique comment détecter l'artefact dans des données que vous possédez déjà, pourquoi la correction évidente est fausse elle aussi, et où se situe la limite honnête de tout l'exercice.
La signature : une frontière qui se déclenche zéro fois
Le signe révélateur n'est pas qu'un nom ait l'air bizarre. Les noms ont l'air bizarre. Le signe révélateur, c'est un caractère de frontière qui ne produit pas une seule majuscule dans tout un fichier.
Voici notre corpus français de prénoms, construit à partir du registre national des noms de naissance. Nous avons compté chaque trait d'union et chaque apostrophe à l'intérieur d'un nom, puis demandé quel type de lettre suit :
| Fichier | Après - : majuscule | Après - : minuscule | Après ' : majuscule | Après ' : minuscule |
|---|---|---|---|---|
fr_FR firstname_male | 1 359 | 0 | 0 | 32 |
fr_FR firstname_female | 1 525 | 0 | 0 | 22 |
2 884 traits d'union, chacun sans exception suivi d'une majuscule : Jean-Pierre, Marie-Claire, Anne-Sophie. 54 apostrophes, aucune suivie d'une majuscule.
Ce n'est pas un fait linguistique concernant le français. C'est une signature de machine. Ce qui a remis ce fichier en casse a traité - comme une frontière de mot et ' comme une lettre ordinaire. Un transcripteur humain produit un mélange ; une règle produit une colonne de zéros.
Ce que contiennent réellement les entrées à apostrophe :
M'hamed M'barek M'baye N'guessan N'diaye N'deye N'faly R'kia ← correct as-is
O'bryan O'neal O'brian O'neil O'neill Jo'anna Carol'ann Lou'ann ← wrong
Et c'est pour cela que le défaut survit à la relecture. La majorité de ces noms — l'arabe M'hamed, les ouest-africains N'diaye, N'guessan — sont correctement en minuscule après l'apostrophe. Les formes cassées se cachent parmi eux. Qui parcourt le fichier des yeux voit un mélange plausible de noms maghrébins et sahéliens, et passe à la suite.
Voyez à l'inverse un fichier dont la casse n'a pas été refaite mécaniquement. Sur l'ensemble des 64 locales que nous livrons, voici ce qui suit une apostrophe :
| Locale | Majuscule après ' | Minuscule après ' | Lecture |
|---|---|---|---|
en_US | 55 | 0 | O'Brien, O'Neill, D'Angelo |
en_GB | 55 | 0 | |
en_IE | 44 | 0 | O'Brien, O'Sullivan, O'Donnell |
en_AU | 25 | 0 | |
en_NZ | 22 | 4 | O'Brien et Su'a, Papali'i, Fa'alogo |
it_IT | 12 | 0 | D'Angelo, Dell'Aquila |
fr_FR | 1 | 54 | ⚠ inversé |
en_NZ est la ligne intéressante, et celle qui met fin à l'argument en faveur d'une règle mécanique. Elle contient les deux conventions, toutes deux correctes : l'irlandais O'Brien prend une majuscule après l'apostrophe, et les samoans Su'a, Fa'alogo, Fepulea'i, Papali'i n'en prennent pas, parce que l'apostrophe y est une consonne occlusive glottale (le ʻokina), et non une frontière de mot. Un fichier, un pays, deux règles opposées, aucun moyen de trancher à partir de la chaîne.
Les deux cas où nous nous sommes trompés
en_IE : Mckeever → McKeever. Simple, repéré et corrigé.
vi_VN : Tôn-nữ → Tôn Nữ et Tôn-thất → Tôn Thất. Corrigé le 21 juillet 2026, et il vaut la peine de l'expliquer, car l'argument selon lequel il s'agit d'un bogue — et non d'une variante orthographique légitime — est structurel et non esthétique.
Les noms de famille composés vietnamiens n'ont connu que deux normes écrites :
| Norme | Écriture | Deuxième syllabe |
|---|---|---|
| Moderne (après les années 1950) | Tôn Thất, Tôn Nữ | majuscule |
| Ancienne à trait d'union (avant) | Tôn-Thất, Việt-Nam | majuscule |
La deuxième syllabe d'un nom propre vietnamien porte une majuscule dans les deux. Il n'a jamais existé de norme où elle soit en minuscule. Tôn-nữ n'est donc ni un archaïsme, ni une variante régionale, ni une graphie de la source — c'est exactement ce que produit ucfirst(strtolower("TÔN-NỮ")). Deux normes connues, et la chaîne ne correspond à aucune des deux : voilà un argument plus fort que « cela me semble faux ».
Nous avons retenu la forme avec espace plutôt que Tôn-Nữ, parce que le reste du corpus vietnamien utilise déjà l'espace pour les unités plurisyllabiques — 49 prénoms séparés par une espace dans le fichier masculin, 79 dans le fichier féminin, et zéro trait d'union où que ce soit dans les noms vietnamiens. État actuel : Tôn Nữ (rang 122, poids 17) et Tôn Thất (rang 147, poids 12) sur 298 noms de famille, plus aucun trait d'union.
Nous avons ensuite balayé les 64 locales à la recherche du même motif — trait d'union suivi d'une lettre minuscule — et trouvé trois survivants :
| Entrée | Locale | Verdict |
|---|---|---|
Perangin-angin | id_ID | Correct. Réduplication batak ; le second élément n'est pas un mot à part. |
Karo-karo | id_ID | Correct. Idem. |
Jo-anne | en_NZ | Réellement attesté à côté de Jo-Anne. |
Trois occurrences, et la règle automatique aurait « corrigé » les trois en erreurs.
Le plus gros, que nous n'avons pas corrigé : 158 prénoms
Les noms de famille de nos locales anglaises sont propres. Les prénoms ne le sont pas, et les chiffres disent exactement où s'est arrêtée la frontière du nettoyage :
| Locale | Mc + majuscule | Mc + minuscule | O' + majuscule | O' + minuscule |
|---|---|---|---|---|
en_IE | 64 | 0 | 43 | 0 |
en_GB | 52 | 0 | 37 | 0 |
en_US | 57 | 0 | 47 | 0 |
en_AU | 73 | 0 | 25 | 0 |
en_NZ | 99 | 0 | 22 | 0 |
Zéro sur toute la ligne — dans les fichiers de noms de famille. Dans les fichiers de prénoms en_US, il y a 158 entrées commençant par Mc + minuscule, qui totalisent un poids de 148 225 sur 282 696 333 (0,052 %) : Mckenzie (55 094), Mckenna (36 825), Mckayla (11 415), Mckinley (9 468).
La preuve qu'il s'agit d'un artefact de pipeline et non de deux conventions de nommage différentes, c'est que les mêmes chaînes apparaissent dans les deux fichiers, avec une casse différente, au sein du même corpus :
| Comme prénom | Poids | Comme nom de famille | Poids |
|---|---|---|---|
Mckenzie | 1 795 | McKenzie | 58 046 |
Mccoy | 2 330 | McCoy | 107 288 |
Mcdonald | 466 | McDonald | 172 700 |
Mcdaniel | 197 | McDaniel | 84 533 |
Macdonald | 288 | MacDonald | 45 126 |
Dejesus | 141 | DeJesus | 46 493 |
Mckeever | 5 | McKeever | 7 036 |
Vingt collisions de ce type. Même population source, même organisation, deux décisions de casse différentes — parce qu'un fichier est passé par une liste d'exceptions constituée à la main et l'autre par ucfirst.
La source est en majuscules, et elle a déjà jeté des choses
Bon à savoir avant d'écrire votre outil de remise en casse : le registre dont vous refaites la casse a peut-être détruit davantage que la casse.
Les deux produits de noms du recensement américain 2020 stockent les noms en majuscules, et nous avons compté ce qu'ils contiennent :
| Mesure | Prénoms | Noms de famille |
|---|---|---|
| Lignes de noms dans le fichier | 53 618 | 156 622 |
| Lignes contenant une apostrophe | 0 | 0 |
O'BRIEN | 0 | 0 |
OBRIEN | 1 | 1 |
O'NEILL / ONEILL | 0 / 1 | 0 / 1 |
D'AMICO / DAMICO | 0 / 1 | 0 / 1 |
Le Census Bureau ne se contente pas de mettre les noms en majuscules ; il supprime entièrement l'apostrophe. O'Brien est publié sous la forme OBRIEN. Le O'Brien de poids 115 547 de notre corpus n'est donc pas une donnée de la source — c'est une reconstruction, faite par quelqu'un qui savait que OBRIEN est O'Brien et non Obrien. Cette reconstruction relève du savoir, pas de la transformation, et aucune signature de fonction ne peut l'encoder.
C'est le même schéma que la suppression des accents dans les registres espagnols : le registre normalise pour sa propre comparabilité, et la normalisation est irréversible sans connaissance extérieure.
Pourquoi ucfirst et ucwords sont irréparables
La tentation, après avoir vu tout cela, est d'en écrire une meilleure : découper sur -, ', , puis mettre chaque morceau en majuscule initiale. Cela produit M'Hamed, N'Diaye, Su'A, Papali'I, Van Der Berg, De La Cruz, Al-Ahmad. Vous avez échangé une erreur uniforme contre une autre.
Quatre problèmes distincts s'empilent les uns sur les autres, et seul le premier concerne les frontières de mots.
1. L'ensemble des caractères de frontière n'est pas [ -]. Il vous faut au minimum -, ', ’ (U+2019, que les données réelles contiennent à côté de U+0027), l'espace et le . des initiales. ucfirst n'en gère aucun. ucwords gère l'espace et prend en PHP une liste explicite de délimiteurs précisément parce qu'il n'existe pas de valeur par défaut correcte.
2. Tout caractère de frontière n'est pas une frontière. Établi par les données ci-dessus : l'apostrophe est une frontière dans O'Brien et une consonne dans Su'a ; le trait d'union est une frontière dans Jean-Pierre et interne dans Karo-karo. Le même caractère, dans le même fichier, signifie deux choses.
3. Certains éléments doivent rester en minuscules, et lesquels dépend de la langue. Les néerlandais van, de, van der, ten s'écrivent en minuscules après un prénom et avec une majuscule sans prénom — une règle de position, pas une orthographe figée. Le néerlandais de Belgique fige ce que l'état civil a enregistré, si bien que De Smet est De Smet partout. L'arabe bin, bint, al- ; le portugais dos, da ; le français de, du ; l'allemand von, zu — chacun a sa propre convention, et appliquer la règle néerlandaise à un nom belge, ou la règle allemande à un nom portugais, produit une véritable erreur dans les deux sens.
4. strtolower lui-même est faux pour certaines écritures. strtolower en PHP travaille sur les octets et abîme l'UTF-8 (mb_strtolower est le minimum). Le turc a un i avec point et un sans point : İSTANBUL ne donne istanbul en minuscules que sous une locale turque, et i̇stanbul sinon. Le sigma final grec change de forme selon sa position. Et en géorgien — que nous livrons — le mkhedruli n'a pas de casse du tout ; un balayage naïf à la recherche des « noms commençant par une minuscule » signale comme suspectes les 1 036 entrées géorgiennes, et toutes sont parfaitement correctes.
La liste d'exceptions est obligatoire, et elle dépend de la langue
Vous ne pouvez pas éviter une liste. Mc, Mac, O', Fitz, van, de, von, bin, al-, Ó, Ní, Le, D'. Très bien — sauf que la liste ne partitionne pas non plus proprement les données, et notre corpus contient les contre-exemples :
| Entrée | Locale | Ce que ferait une règle Mac/Mc | Réalité |
|---|---|---|---|
Mchunu | en_ZA | → McHunu | Nom de famille zoulou. Mc n'est pas du tout un préfixe. |
Machaba | en_ZA | → MacHaba | Zoulou également, et pas davantage un préfixe. |
Macias | en_US | → MacIas | L'espagnol Macías. Pas un préfixe. |
Mack | en_US | → MacK | Un nom de famille à part entière (69 776). |
Macken | en_IE | → MacKen | Irlandais, correctement Macken. |
Mackey | en_IE | → MacKey | Irlandais, correctement Mackey. |
Macon | en_US | → MacOn | Pas un préfixe. |
La liste doit donc être une liste de noms, et non de préfixes. Ce qui signifie qu'elle doit être construite à partir d'une source qui consigne les graphies réelles, c'est-à-dire précisément ce dont vous ne disposiez pas au départ.
Et puis il y a Macdonald
Le cas véritablement insoluble, et nous préférons le dire clairement plutôt que de vous laisser croire qu'il existe une liste suffisamment bonne.
| Locale | Graphie | Porteurs |
|---|---|---|
en_US | McDonald | 172 700 |
en_US | MacDonald | 45 126 |
en_GB | McDonald | 31 974 |
en_GB | Macdonald | 21 737 |
en_CA | MacDonald | 19 |
en_AU | Macdonald | 4 |
Macdonald et MacDonald sont deux noms de famille bien réels, portés par des familles différentes, et ils ne sont pas plus des variantes l'un de l'autre que Smith et Smyth. Dans notre corpus britannique, la forme à minuscule médiane compte 21 737 porteurs ; dans notre corpus américain, la forme à majuscule médiane en compte 45 126. Aucune n'est une faute de frappe de l'autre. Il n'existe aucune règle — ni règle de locale, ni règle de fréquence, ni règle écossais-contre-irlandais — qui décide à laquelle des deux appartient une personne donnée.
Il en va de même pour Mackenzie / MacKenzie / McKenzie, et pour Vandenberghe face à Van den Berghe dans les données belges, où la forme soudée et la forme séparée sont des noms de famille légalement distincts, appartenant à des familles distinctes.
Toute normalisation qui fait correspondre ces formes entre elles détruit des personnes réelles. C'est le plafond de tout ce problème : non pas « difficile à automatiser », mais aucune réponse correcte n'existe en tant que fonction de la chaîne.
Ce qui fonctionne vraiment
1. Ne refaites pas la casse du tout si vous pouvez l'éviter. Si la source livre une casse mixte, conservez-la octet pour octet. Toute transformation est une occasion de perdre quelque chose, et aucune transformation n'ajoute d'information.
2. Si vous devez refaire la casse d'une source en majuscules, traitez cela comme une reconstruction, pas comme une mise en forme. Une reconstruction demande des preuves : une seconde source en casse mixte, une liste constituée à la main, ou un humain. Budgétez en conséquence, et consignez quelles lignes ont été reconstruites.
3. Auditez avec le test de frontière, pas en lisant. Pour chaque caractère de frontière, comptez combien de fois il est suivi d'une majuscule et combien de fois d'une minuscule, fichier par fichier. Une colonne de zéros purs dans un sens ou dans l'autre, c'est une machine, pas une langue. Ce test a trouvé nos trois défauts et a coûté une douzaine de lignes de code.
4. Ne refaites jamais la casse à l'affichage. Si votre gabarit appelle une fonction de mise en majuscules au moment du rendu d'un nom, vous avez déplacé le bogue à l'endroit où il est le moins visible et le plus difficile à tester. Normalisez une seule fois, à l'ingestion, délibérément, et stockez le résultat.
5. Validez sur la capacité à être affiché, pas sur la forme. ^[A-Z] comme règle de validation d'un nom rejette dela Cruz — le nom de famille le plus répandu aux Philippines — et da Silva, qui figurent tous deux dans notre corpus comme des entrées correctement à initiale minuscule, et elle rejette tous les noms géorgiens qui aient jamais été écrits.
6. Séparez la casse d'affichage de la casse stockée. Un nom de famille rendu seul — dans un index trié, une colonne de tableau, une formule d'adresse — peut légitimement demander une casse différente de celle du même nom placé après un prénom. C'est une fonction de rendu avec un argument de locale, pas une propriété de la chaîne stockée.
Limites connues
- Nous n'avons pas corrigé les 158 prénoms
Mc*deen_US. Ils représentent 0,052 % du poids des prénoms, et les corriger suppose de décider, nom par nom, siMckenzieen tant que prénom est unMcKenziemal mis en casse ou une graphie moderne distincte que des parents déclarent réellement — et pour les prénoms, contrairement aux noms de famille, la seconde lecture est véritablement plausible. Jo-annedansen_NZn'est pas tranché.Jo-annecommeJo-Annesont attestés. Nous avons conservé la graphie de la source.- Les entrées à apostrophe de
fr_FRne sont pas corrigées. Nous pouvons identifierO'bryan,O'nealetO'briancomme des artefacts avec certitude ; nous ne pouvons pas les séparer mécaniquement de la quarantaine de noms maghrébins et ouest-africains correctement en minuscules du même fichier, et aucune décision nom par nom n'a été prise. - Nous avons mesuré notre propre corpus, pas le monde. Les comptages de
-/', les inventaires de préfixes et les collisions prénom/nom de famille sont tous des mesures des fichiers que nous livrons, prises le 21 juillet 2026. Ce sont des éléments de preuve sur le comportement de cette classe de bogues, pas un recensement de celle-ci.
Données arrêtées au 2026-07-21
64 locales analysées. Noms de famille vi_VN : 298 entrées, un poids total de 99 441, 0 trait d'union, Tôn Nữ et Tôn Thất sous la forme corrigée ; fichiers masculin et féminin identiques octet pour octet. en_US : 2 064 noms de famille et 53 618 lignes de prénoms dans la source. Fichiers du recensement américain 2020 comptés directement. Tous les chiffres ont été recalculés pour cette page, et non repris de notes antérieures.