Regex numéro de TVA intracommunautaire français
Un numéro de TVA français, ce n'est pas juste « FR » suivi de 11 chiffres : la clé de 2 caractères après « FR » peut aussi contenir une lettre (mais jamais I ni O, pour éviter la confusion avec 1 et 0). La réponse la plus votée sur Stack Overflow, tirée du Regular Expressions Cookbook, ne fait pas cette exclusion et rend même le préfixe pays optionnel — ce qui laisse passer un SIREN nu. Voici un motif qui corrige ces deux points, comparé à cette réponse et à deux tentatives bien plus permissives.
/^FR[0-9A-HJ-NP-Z]{2}[0-9]{9}$/ipasse 24/24 cas
Comparatif des patterns existants
| Source | pattern | Score sur le corpus | ReDoS |
|---|---|---|---|
| Stack Overflow — réponse à 52 votes citant le Regular Expressions Cookbook, préfixe pays optionnel et lettres I/O non exclues | ^(FR)?[0-9A-Z]{2}[0-9]{9}$ | 21 / 24 | sûr |
| Stack Overflow — motif générique « simple » pour toute TVA de l'UE, 5 votes, non spécifique à la structure française | ^[A-Za-z]{2,4}(?=.{2,12}$)[-_\s0-9]*(?:[a-zA-Z][-_\s0-9]*){0,2}$ | 18 / 24 | sûr |
| Stack Overflow — tentative de l'auteur de la question, accepte une chaîne de lettres pures (bug signalé par l'auteur lui-même) | ([A-Za-z]{2,4})([a-zA-Z0-9\-\_ ]{2,12}) | 15 / 24 | sûr |
Implémentation
const re = new RegExp("^FR[0-9A-HJ-NP-Z]{2}[0-9]{9}$", "i");
re.test(input);Limites
- Ne vérifie que la FORME du numéro (préfixe FR, clé de 2 caractères sans I ni O, 9 chiffres) : la clé réelle se calcule à partir du SIREN par [ 12 + 3 × (SIREN mod 97) ] mod 97, un calcul arithmétique qu'une regex ne peut pas effectuer — un numéro syntaxiquement valide peut donc correspondre à une clé incorrecte pour le SIREN donné.
- Ne consulte pas le système VIES de la Commission européenne : seule une requête VIES confirme qu'un numéro est réellement attribué et actif, pas seulement bien formé.
- Exige une chaîne sans séparateurs : les espaces ou tirets couramment utilisés dans l'usage courant (« FR 83 404 833 048 », « FR-83-404833048 ») doivent être retirés avant validation.
- Ne détecte pas spécifiquement les deux confusions les plus fréquentes côté utilisateur — saisir le SIREN seul (9 chiffres, sans FR ni clé) ou le SIRET (SIREN + 5 chiffres d'établissement) à la place du numéro de TVA : ces deux cas sont simplement rejetés comme n'importe quelle chaîne mal formée, sans message dédié.