Regex for Indian Vehicle Number Validation — RTO Format & BH Series Explained
Indian vehicle registration numbers follow a format issued by the Regional Transport Office (RTO), but forms that collect them rarely validate the structure properly. This guide breaks down the standard format, gives you a working regex, and covers the newer BH (Bharat) series that many teams forget to handle.
The Standard RTO Format
A typical Indian number plate looks like MH12AB1234 and breaks down into four segments:
- State code — 2 letters, e.g. MH (Maharashtra), DL (Delhi), KA (Karnataka)
- RTO code — 1 or 2 digits identifying the district RTO office, e.g. 12
- Series — 1 to 3 letters (sometimes just 1, sometimes 2), assigned sequentially as registrations are issued, e.g. AB
- Unique number — always 4 digits, e.g. 1234
Plates are printed without spaces, but many forms and older records store them with spaces or hyphens (MH 12 AB 1234 or MH-12-AB-1234), so your regex should tolerate both.
Regex for the Standard Format
// Matches MH12AB1234, MH 12 AB 1234, MH-12-AB-1234
const vehicleRegex = /^[A-Z]{2}[ -]?[0-9]{1,2}[ -]?[A-Z]{1,3}[ -]?[0-9]{4}$/;
function isValidVehicleNumber(input) {
const normalized = input.trim().toUpperCase();
return vehicleRegex.test(normalized);
}
isValidVehicleNumber('MH12AB1234'); // true
isValidVehicleNumber('DL-3C-AA-0001'); // true
isValidVehicleNumber('KA 05 MJ 2311'); // true
isValidVehicleNumber('MH1AB123'); // false — too few digitsThe BH (Bharat) Series Format
Since 2021, vehicle owners with jobs that require frequent inter-state transfers (defence personnel, central government employees, employees of companies with offices in 4+ states) can opt for the BH series, which does not need re-registration when moving states. Its format is different: YY BH #### XX, e.g. 22 BH 1234 AB.
// Matches 22BH1234AB, 22 BH 1234 AB, 22-BH-1234-AB
const bhSeriesRegex = /^[0-9]{2}[ -]?BH[ -]?[0-9]{4}[ -]?[A-Z]{1,2}$/;
isValidVehicleNumber = (input) => bhSeriesRegex.test(input.trim().toUpperCase());
isValidVehicleNumber('22BH1234AB'); // true
isValidVehicleNumber('23 BH 5678 A'); // trueCombined Validator for Both Formats
In most real applications (insurance forms, parking apps, fleet management systems) you want to accept either format:
function isValidIndianVehicleNumber(input) {
const value = input.replace(/[\s-]/g, '').toUpperCase();
const standard = /^[A-Z]{2}[0-9]{1,2}[A-Z]{1,3}[0-9]{4}$/;
const bhSeries = /^[0-9]{2}BH[0-9]{4}[A-Z]{1,2}$/;
return standard.test(value) || bhSeries.test(value);
}Common Edge Cases to Handle
- Some older plates use a single-letter series instead of two (e.g.
DL1CA1234) - Government vehicles sometimes use series like "GJ" without a numeric RTO code — always double-check against your actual data sample before shipping a strict pattern
- Diplomatic and military vehicles follow entirely different numbering systems and will fail both patterns above — treat them as a separate allow-list if your app must support them
- Always normalize casing and strip spaces/hyphens before matching so formatting differences don't cause false rejections
- Regex confirms format only — it does not verify the vehicle actually exists in the VAHAN database; use the government's VAHAN e-services API for that
Frequently Asked Questions
The standard format is two letters for the state code, one or two digits for the RTO code, one to two (sometimes up to four) letters for the series, and four digits for the unique number, e.g. MH12AB1234.
A practical pattern is ^[A-Z]{2}[ -]?[0-9]{1,2}[ -]?[A-Z]{1,3}[ -]?[0-9]{4}$, applied to the uppercase, trimmed string. It allows optional spaces or hyphens between segments.
The BH (Bharat) series, introduced in 2021, uses the format YY BH #### XX — a 2-digit year of registration, the fixed code BH, four digits, and two letters. It allows a vehicle to move between states without re-registration and needs a separate regex pattern.