/^/
MediumValidation5 min read

Vehicle Identification Number (VIN) Regex

Validates that a string is a 17-character Vehicle Identification Number using only the characters the VIN standard allows, excluding the letters I, O, and Q to avoid confusion with 1 and 0.

#vin#vehicle#validation#automotive#identifier

Regex Pattern

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

Pattern Breakdown

Hover over a token to see what it does.

^[A-HJ-NPR-Z0-9]{17}$
TokenMeaning
^Anchors the match to the start of the string
[A-HAllows letters A through H
J-NAllows letters J through N, skipping the excluded letter I
PR-Z0-9]Allows P, then R through Z (skipping the excluded letters O and Q), plus all digits 0-9
{17}Exactly 17 characters total, the fixed length mandated by ISO 3779
$Anchors the match to the end of the string

Detailed Explanation

What it does

This pattern checks that a string is exactly 17 characters long and made up only of uppercase letters and digits allowed in a VIN, explicitly excluding I, O, and Q because they are too easily confused with 1 and 0 when handwritten or printed.

Why it works

The VIN standard (ISO 3779, adopted by NHTSA and manufacturers worldwide) fixes the length at 17 and forbids I, O, and Q by specification, so a single character class built by removing those three letters from A-Z, combined with an exact `{17}` count, captures the full allowed alphabet and length in one pass.

Common use cases

  • Validating VIN input fields on vehicle registration, insurance quote, or dealership forms
  • Sanity-checking VINs scanned via barcode or OCR before a decode API lookup
  • Filtering bulk vehicle inventory imports for structurally invalid VINs
  • Client-side format checks before calling a VIN decoder service (e.g. NHTSA vPIC API)

Edge cases

  • A VIN containing 'I', 'O', or 'Q' is correctly rejected even though those look superficially like valid letters
  • Pre-1981 vehicles may have non-standard VIN lengths or formats that this modern 17-character pattern will reject
  • This pattern is case-sensitive; lowercase VINs like '1hgcm82633a004352' fail unless the input is uppercased first or an 'i' flag is added
  • A VIN passing this format check can still fail the official check-digit (position 9) validation used in North America

Limitations

  • Does not verify the position-9 check digit that North American VINs use to detect transcription errors
  • Does not confirm the VIN was actually assigned to a real, manufactured vehicle
  • Cannot decode or validate the embedded manufacturer, model, or plant codes without a separate lookup
  • Pre-1981 VINs with variable length and format are out of scope for this modern fixed-length pattern

Interactive Tester

Edit the pattern or text below — matching runs live in your browser.

1HGCM82633A004352 5YJSA1E26FF001234

Test Cases

Editable — add your own inputs to see if they pass.

InputExpectedResult
Pass
Pass
Pass
Pass
Pass
Pass
Pass
Pass

Language Variants

Production-ready examples in 12 languages.

const vinRegex = /^[A-HJ-NPR-Z0-9]{17}$/;
console.log(vinRegex.test('1HGCM82633A004352')); // true

Common Mistakes

Using a plain [A-Z0-9]{17} class and forgetting to exclude I, O, and Q

Fix: Build the character class explicitly as [A-HJ-NPR-Z0-9] to match the real VIN standard

Treating a format-valid VIN as fully verified

Fix: Also validate the position-9 check digit and/or decode the VIN through NHTSA's vPIC API for full confidence

Rejecting lowercase VINs from OCR or barcode scans without normalizing case first

Fix: Uppercase the scanned input before validation, or add the case-insensitive flag if lowercase VINs are expected

Performance Notes

  • A single fixed-length character class with {17} is O(n) with no backtracking possibility
  • Anchoring the full string prevents accidental partial matches inside longer text blobs
  • For batch VIN validation over large datasets, reuse one compiled regex instance rather than recompiling per row

Browser Compatibility

EngineSupportedNotes
ChromeYes
FirefoxYes
SafariYes
EdgeYes
Node.jsYes