27

I have written a VIN validation RegEx based on the http://en.wikipedia.org/wiki/Vehicle_identification_number but then when I try to run some tests it is not accepting some valid VIN Numbers.

My RegEx:

^[A-HJ-NPR-Za-hj-npr-z\\d]{8}[\\dX][A-HJ-NPR-Za-hj-npr-z\\d]{2}\\d{6}$

VIN Number Not Working:
1ftfw1et4bfc45903
WP0ZZZ99ZTS392124

VIN Numbers Working:
19uya31581l000000
1hwa31aa5ae006086

(I think the problem occurs with the numbers at the end, Wikipedia made it sound like it would end with only 6 numbers and the one that is not working but is a valid number only ends with 5)

Any Help Correcting this issue would be greatly appreciated!

2
  • 1
    The Wikipedia spec you gave shows that there are many different styles of VIN numbers. Which ones are you trying to match? Commented May 19, 2015 at 0:30
  • errrr it has to detect all Vin Numbers :( I thought the one I had above does so :(
    – Vicki
    Commented May 19, 2015 at 0:32

8 Answers 8

24

I can't help you with a perfect regex for VIN numbers -- but I can explain why this one is failing in your example of 1ftfw1et4bfc45903:

^[A-HJ-NPR-Za-hj-npr-z\d]{8}[\dX][A-HJ-NPR-Za-hj-npr-z\d]{2}\d{6}$

Explanation:

  • ^[A-HJ-NPR-Za-hj-npr-z\d]{8}
    This allows for 8 characters, composed of any digits and any letters except I, O, and Q; it properly finds the first 8 characters:
    1ftfw1et
  • [\dX]
    This allows for 1 character, either a digit or a capital X; it properly finds the next character:
    4
  • [A-HJ-NPR-Za-hj-npr-z\d]{2}
    This allows for 2 characters, composed of any digits and any letters except I, O, and Q; it properly finds the next 2 characters:
    bf
  • \d{6}$
    This allows for exactly 6 digits, and is the reason the regex fails; because the final 6 characters are not all digits:
    c45903
0
13

Dan is correct - VINs have a checksum. You can't utilize that in regex, so the best you can do with regex is casting too wide of a net. By that I mean that your regex will accept all valid VINs, and also around a trillion (rough estimate) non-VIN 17-character strings.

If you are working in a language with named capture groups, you can extract that data as well.

So, if your goal is:

  • Only to not reject valid VINs (letting in invalid ones is ok) then use Fransisco's answer, [A-HJ-NPR-Z0-9]{17}.

  • Not reject valid VINs, and grab info like model year, plant code, etc, then use this (note, you must use a language that can support named capture groups - off the top of my head: Perl, Python, Elixir, almost certainly others but not JS): /^(?<wmi>[A-HJ-NPR-Z\d]{3})(?<vds>[A-HJ-NPR-Z\d]{5})(?<check>[\dX])(?<vis>(?<year>[A-HJ-NPR-Z\d])(?<plant>[A-HJ-NPR-Z\d])(?<seq>[A-HJ-NPR-Z\d]{6}))$/ where the names are defined at the end of this answer.

  • Not reject valid VINs, and prevent some but not all invalid VINs, you can get specific like Pedro does.

  • Only accept valid VINs: you need to write code (just kidding, GitHub exists).

Capture group name key:

  • wmi - World manufacturer identifier
  • vds - Vehicle descriptor section
  • check - Check digit
  • vis - Vehicle identifier section
  • year - Model year
  • plant - Plant code
  • seq - Production sequence number
1
10

This regular expression is working fine for validating US VINs, including the one you described:

[A-HJ-NPR-Z0-9]{17}

Remember to make it case insensitive with flag i

Source: https://github.com/rfink/angular-vin

7

VIN should have only A-Z, 0-9 characters, but not I, O, or Q
Last 6 characters of VIN should be a number
VIN should be 17 characters long

You didn't specify which language you're using but the following regex can be used to validate a US VIN with php:

/^(?:([A-HJ-NPR-Z]){3}|\d{3})(?1){2}\d{2}(?:(?1)|\d)(?:\d|X)(?:(?1)+\d+|\d+(?1)+)\d{6}$/i
5
  • 2
    the last 6 characters are not always 6 numbers like the example above
    – Vicki
    Commented May 19, 2015 at 0:48
  • The example above if for US. There are many types o VIN's, which type are you trying to match ? All the VINS present on the wiki page you've posted have 6 digits at the end. Commented May 19, 2015 at 0:53
  • You may want to take a look at the following question stackoverflow.com/questions/26594504/… Commented May 19, 2015 at 0:58
  • Last 6 chars are number, this isn't universally true en.wikipedia.org/wiki/Vehicle_identification_number
    – weston
    Commented Jun 27, 2016 at 9:24
  • VIN can range from 11 to 17 characters if the vehicle was manufactured before 1981 so checking for a length of 17 will not work in all cases.
    – zgr024
    Commented Feb 12, 2020 at 19:16
4

I feel regex is not the ideal validation. VINs have a built in check digit. https://en.wikibooks.org/wiki/Vehicle_Identification_Numbers_(VIN_codes)/Check_digit or http://www.vsource.org/VFR-RVF_files/BVINcalc.htm

I suggest you build an algorithm using this. (Untested algorithm example)

1

This should work, it is from splunk search, so there are some additional exclusions**

(?i)(?<VIN>[A-Z0-9^IOQioq_]{11}\d{6})
1

The NHTSA website provides the method used to calculate the 9th character checksum, if you're interested. It also provides lots of other useful data, such as which characters are allowed in which position, or how to determine whether the 10th character, if alphabetic, refers to a model year up to 1999 or a model year from 2010.

NHTSA VIN eCFR

Hope that helps.

1
  • 1
    You might want to edit this link to remove the session id (SID=e9e04d1dbab6285f7e27151cad41ed25)
    – S. Imp
    Commented Nov 12, 2019 at 15:53
1

Please, use this regular expression. It is shorter and works with all VIN types

(?=.*\d|[A-Z])(?=.*[A-Z])[A-Z0-9]{17}

I changed above formula by new below formula

(?=.*\d|=.*[A-Z])(?=.*[A-Z])[A-Z0-9]{17}

This regular expression consider any letter but at leats one digit, max 17 characters

1
  • Please adjust your regex because it is not accurate. The VIN specification doesn't allow for a letter "I" as the first character which will be accepted with .*[A-Z]
    – voidmain
    Commented May 13, 2022 at 15:23

Not the answer you're looking for? Browse other questions tagged or ask your own question.