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.
Regex Pattern
^[A-HJ-NPR-Z0-9]{17}$Pattern Breakdown
Hover over a token to see what it does.
| Token | Meaning |
|---|---|
| ^ | Anchors the match to the start of the string |
| [A-H | Allows letters A through H |
| J-N | Allows 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.
Test Cases
Editable — add your own inputs to see if they pass.
| Input | Expected | Result | |
|---|---|---|---|
| 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')); // trueCommon 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
| Engine | Supported | Notes |
|---|---|---|
| Chrome | Yes | — |
| Firefox | Yes | — |
| Safari | Yes | — |
| Edge | Yes | — |
| Node.js | Yes | — |
Work with this pattern
Take this expression further — test it against your own data, adapt it in the builder, or read up on the syntax behind it.
Regex Tester
Test a regular expression against sample text and see every match highlighted live.
Regex Generator
Build a pattern by clicking blocks — no syntax memorisation required.
Regular Expressions Guide
What regex is, how the syntax works, and the mistakes that trip people up.
Regex Cheat Sheet
Every token, quantifier, and assertion on one printable page.
Python Regex Guide
The re module end to end — search, match, findall, groups, and substitution.
Regex Pattern Library
100+ ready-to-use patterns for email, URLs, dates, IPs, and more.