Regex Spanish DNI/NIE
A Spanish DNI isn't just "8 digits + a letter": the check letter comes from a fixed 23-letter table (I, O, U are deliberately excluded to avoid confusion with 1, 0, U), computed via modulo 23 on the 8 digits. A RegexTester pattern nonetheless accepts any letter A-Z, I/O/U included. The best answer found, with 32 votes on Spanish Stack Overflow, does correctly restrict to the 23 valid letters - but its own author states it plainly: "Pero eso es para comprobar el formato" (but that's just to check the format). No regex alone can verify the modulo 23 computation itself. Here's a pattern that at least respects the correct letter table, compared against these three attempts.
/^(?:[0-9]{8}|[XYZ][0-9]{7})[TRWAGMYFPDXBNJZSQVHLCKE]$/ipasses 20/20 cases
Comparison of existing patterns
| Source | pattern | Score on the corpus | ReDoS |
|---|---|---|---|
| RegexTester — accepte n'importe quelle lettre A-Z, y compris I/O/U qui ne sont jamais des lettres de contrôle valides, sans jamais vérifier le calcul | ^[0-9]{8,8}[A-Za-z]$ | 16 / 20 | safe |
| Gist GitHub (afgomez) — le NIE autorise à tort 7 OU 8 chiffres (toujours 7 en réalité), le DNI accepte n'importe quelle lettre au lieu des 23 valides | ^[XYZ]\d{7,8}[A-Z]$ | 16 / 20 | safe |
| Stack Overflow en español (32 votes) — restreint correctement aux 23 lettres valides, mais l'auteur précise lui-même que ça ne vérifie que le FORMAT : un DNI 12345678A passe cette regex alors que la lettre correcte est Z | ^[XYZ][0-9]{7}[TRWAGMYFPDXBNJZSQVHLCKE]$ | 17 / 20 | safe |
Implementation
const re = new RegExp("^(?:[0-9]{8}|[XYZ][0-9]{7})[TRWAGMYFPDXBNJZSQVHLCKE]$", "i");
re.test(input);Limits
- Valide seulement la FORME (8 chiffres ou X/Y/Z + 7 chiffres, lettre parmi les 23 valides) : ne calcule pas le modulo 23 lui-même — un DNI syntaxiquement valide selon ce motif peut avoir une lettre fausse par rapport à son numéro (voir 12345678A dans les exemples, structure correcte mais lettre fausse : la bonne serait Z).
- Ne consulte aucun registre du Ministerio del Interior : seule une vérification administrative confirme qu'un DNI/NIE est réellement attribué à une personne.
- Ne distingue pas dans son résultat le DNI (citoyens espagnols) du NIE (résidents étrangers) : les deux partagent la même famille de format, seule la présence d'un préfixe X/Y/Z les différencie.
- N'accepte que la forme sans séparateur : la présentation parfois utilisée à l'affichage avec un tiret avant la lettre (« 12345678-Z ») doit être retirée avant validation par ce motif.