Rexact
Cheatsheet

Regex VIN (vehicle identification number)

The reference Stack Overflow question's author had a very concrete bug: their regex rejected two real VINs because it required the last 6 characters to be digits only. The top-voted answer spells it out plainly: in the VIN "1ftfw1et4bfc45903", the last 6 characters are "bfc45903" - which contain letters. Another answer, very permissive (just 17 characters excluding the letters I/O/Q), is called a "too wide a net" by a competing answer. A third uses PCRE recursive-subpattern syntax that simply doesn't compile in JavaScript. Here's a pattern that respects the real structure (a check digit at position 9, a digit or X), compared against these 3 real attempts.

/^[A-HJ-NPR-Z0-9]{8}[0-9X][A-HJ-NPR-Z0-9]{8}$/i
passes 20/20 cases

Comparison of existing patterns

Implementation

const re = new RegExp("^[A-HJ-NPR-Z0-9]{8}[0-9X][A-HJ-NPR-Z0-9]{8}$", "i");
re.test(input);

Limits

  • Scope limité aux VIN nord-américains (NHTSA/SAE J853, en vigueur depuis 1981) : les VIN européens et de nombreux autres pays suivent uniquement la norme ISO 3779 de base, sans clé de contrôle à la position 9 — un vrai VIN européen valide peut donc être rejeté à tort par ce motif (signalé en commentaire sur le fil source).
  • Ne vérifie pas la clé de contrôle elle-même (calcul pondéré modulo 11 défini par la NHTSA) : seule sa position et son alphabet (chiffre ou X) sont vérifiés, pas sa valeur réelle par rapport aux 16 autres caractères.
  • Ne couvre pas les véhicules d'avant 1981, dont le VIN pouvait compter de 11 à 17 caractères sans structure standardisée.
  • Une chaîne de 17 caractères syntaxiquement valide selon ce motif n'est pas nécessairement un VIN réellement attribué à un véhicule existant : la forme ne garantit ni l'existence ni la cohérence du code constructeur (WMI) avec le reste du numéro.