Rexact
Cheatsheet

Regex Italian VAT number (partita IVA)

The Italian partita IVA has 11 digits: a 7-digit serial, a 3-digit code of the office (ufficio) that issued the number, then a Luhn-type check digit defined by the ministerial decree of 23 December 1976. The office code matches a province: 001 to 100, 120 and 121, plus 888 (franchise regime) and 999 (non-residents identified in Italy). The Commission's VIES FAQ only publishes 'IT + 11 digits', and the three VAT implementations read (validator.js, jsvat, valvat) check only that, like the Regular Expressions Cookbook's single regex: an office code 000 or 889 slips through. Here's a pattern bounding the office code and rejecting an all-zero serial, compared against those attempts.

/^IT(?!0{7})[0-9]{7}(?:00[1-9]|0[1-9][0-9]|100|12[01]|888|999)[0-9]$/
passes 29/29 cases

Comparison of existing patterns

SourcepatternScore on the corpusReDoS
validator.js (isVAT) — préfixe « IT » facultatif (« 07643520567 » nu passe) ; code d'ufficio non borné : « IT12345670009 » (code 000) passe^(IT)?\d{11}$20 / 29safe
jsvat (italy.ts) — ancrée, préfixe obligatoire, mais la regex ne borne pas le code d'ufficio (le calcul de calcFn le fait à part, jusqu'à 201) : « IT12345670009 » (code 000) et un matricule nul passent^(IT)(\d{11})$21 / 29safe
valvat (syntax.rb, A et Z remplacés par ^ et $) — ancrée, préfixe obligatoire, mais « IT12345670009 » (code 000) et un matricule nul passent^IT[0-9]{11}$21 / 29safe
Regular Expressions Cookbook, recette 4.21 (27 pays en une regex, insensible à la casse) — préfixe facultatif, minuscules acceptées (« it07643520567 »), « FR07643520567 » passe (lu comme une TVA française) et le code d'ufficio n'est pas borné^((AT)?U[0-9]{8}|(BE)?0[0-9]{9}|(BG)?[0-9]{9,10}|(CY)?[0-9]{8}L|(CZ)?[0-9]{8,10}|(DE)?[0-9]{9}|(DK)?[0-9]{8}|(EE)?[0-9]{9}|(EL|GR)?[0-9]{9}|(ES)?[0-9A-Z][0-9]{7}[0-9A-Z]|(FI)?[0-9]{8}|(FR)?[0-9A-Z]{2}[0-9]{9}|(GB)?([0-9]{9}([0-9]{3})?|[A-Z]{2}[0-9]{3})|(HU)?[0-9]{8}|(IE)?[0-9]S[0-9]{5}L|(IT)?[0-9]{11}|(LT)?([0-9]{9}|[0-9]{12})|(LU)?[0-9]{8}|(LV)?[0-9]{11}|(MT)?[0-9]{8}|(NL)?[0-9]{9}B[0-9]{2}|(PL)?[0-9]{10}|(PT)?[0-9]{9}|(RO)?[0-9]{2,10}|(SE)?[0-9]{12}|(SI)?[0-9]{8}|(SK)?[0-9]{10})$18 / 29safe

Implementation

const re = new RegExp("^IT(?!0{7})[0-9]{7}(?:00[1-9]|0[1-9][0-9]|100|12[01]|888|999)[0-9]$", "");
re.test(input);

Limits

  • Valide seulement la FORME : « IT12345670018 » a un code d'ufficio valide mais une clé Luhn fausse et passe ce motif. La clé (décret du 23 décembre 1976) n'est pas recalculée par la regex.
  • La liste des codes d'ufficio (001-100, 120, 121, 888, 999) vient de it.wikipedia et de python-stdnum ; jsvat tolère jusqu'à 201. Si l'administration ajoutait un code, ce motif le refuserait : à relire régulièrement.
  • Le code fiscal d'une personne physique (16 caractères) n'est pas une partita IVA, et un code fiscal de société peut ressembler à une partita IVA : voir la fiche codice-fiscale. Aucune vérification d'existence (VIES).
  • Pas de tolérance pour les espaces ou minuscules ; normalisez avant validation. Les numéros du corpus sont des exemples de documentation ou synthétiques.

Related pages