Regex Portuguese NIF (número de identificação fiscal)
The NIF of an individual is a 9-digit number: the first eight are sequential and the last is a check digit (Decree-Law 14/2013, article 4, and a note from the tax authority AT). An individual's first digit runs from 1 to 4, with '45' for non-residents; legal-entity NIFs start with 5, 6, 7, 8 or 9. The key weights the first eight digits 9, 8, 7, 6, 5, 4, 3, 2: 11 minus the remainder modulo 11, with 10 and 11 brought to 0 (DG TAXUD specification). A regex cannot express it: it checks 9 digits without a leading zero, and you need to add the code check. The real attempts I read disagree on the leading zero, the 'PT' prefix and spaces between groups of 3 digits.
/^[1-9]\d{8}$/passes 24/24 cases
Comparison of existing patterns
| Source | pattern | Score on the corpus | ReDoS |
|---|---|---|---|
| validator.js isTaxID (pt-PT) — ancrée mais « \d{9} » accepte un zéro initial (« 012345674 » à clé valide) que la loi exclut | ^\d{9}$ | 22 / 24 | safe |
| piigex (détecteur pt_nif) — premier chiffre 1-9, mais pas d'ancres de chaîne : « NIF 299999998 » et « x-299999998 » passent | (?<!\d)[1-9]\d{8}(?!\d) | 21 / 24 | safe |
| pii-extract-plg-regex (mode verbeux re.X, espaces retirés) — accepte « PT » et 3 groupes de 3 chiffres, mais zéro initial accepté et non ancrée (« xx299999998yy » passe) | (?:PT\x20?)?(?:\d{3}\x20\d{3}\x20\d{3}|\d{9}) | 17 / 24 | safe |
Implementation
const re = new RegExp("^[1-9]\\d{8}$", "");
re.test(input);Limits
- Valide seulement la FORME : 9 chiffres, premier chiffre non nul. La clé modulo 11 n'est pas vérifiée : « 299999999 » et « 501964842 » passent. Complément : somme = Σ chiffre[i] × (9 − i) pour i de 0 à 7, clé = 11 − somme % 11, ramenée à 0 si elle vaut 10 ou 11.
- Les préfixes valides ne sont pas bornés : la loi donne 1 à 4 pour les personnes physiques (« 45 » non-résidents) mais les préfixes 5 à 9 des personnes morales viennent de sources secondaires, donc un NIF commençant par 4 autre que 45, ou par 8, est accepté.
- Le préfixe « PT » (forme TVA) et les espaces entre groupes sont rejetés : retirez-les avant de valider. Ne vérifie ni l'attribution ni l'existence du contribuable ; n'utilisez en test que des numéros d'exemple ou synthétiques.