Rexact
Cheatsheet

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]$/i
passes 20/20 cases

Comparison of existing patterns

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.