Indian GSTIN Regex
Validates the structural format of a 15-character Indian GST Identification Number (GSTIN): state code, embedded PAN, entity code, the fixed letter Z, and a checksum character.
Regex Pattern
^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z]{1}[1-9A-Z]{1}Z[0-9A-Z]{1}$Pattern Breakdown
Hover over a token to see what it does.
| Token | Meaning |
|---|---|
| ^ | Anchors the match to the start of the string |
| [0-9]{2} | Two-digit state code (e.g. 27 for Maharashtra, 07 for Delhi) |
| [A-Z]{5} | The first five characters of the taxpayer's embedded PAN |
| [0-9]{4} | The four PAN digits |
| [A-Z]{1} | The final PAN check letter |
| [1-9A-Z]{1} | Entity/registration number for this PAN within the state (1-9 then A-Z for more than 9 registrations) |
| Z | Fixed literal 'Z', reserved by default for future use in the GSTIN scheme |
| [0-9A-Z]{1}$ | Final alphanumeric checksum character, then end of string |
Detailed Explanation
What it does
This pattern validates that a string has the exact 15-character structural shape of a GSTIN: a 2-digit state code, a 10-character embedded PAN (5 letters, 4 digits, 1 letter), a 1-character entity code, the fixed letter 'Z', and a final alphanumeric check character. It does not independently verify the embedded PAN or recompute the checksum.
Why it works
GSTIN is a fixed-position code defined by the GST Council, so chaining exact-length character classes in sequence mirrors the specification directly: digits where digits are required, letters where letters are required, and a literal 'Z' at the position the scheme reserves. Anchoring the whole 15-character sequence with `^`/`$` prevents partial or padded matches.
Common use cases
- Validating GSTIN fields on Indian B2B invoicing, e-way bill, or vendor onboarding forms
- Filtering bulk-uploaded vendor/customer master data for structurally invalid tax IDs
- Pre-flight format checks before calling the GST Network (GSTN) verification API
- Extracting GSTIN-shaped tokens from scanned invoice text for further processing
Edge cases
- Lowercase GSTINs are rejected since real GSTINs are always issued in uppercase and the pattern is case-sensitive
- The 13th character (entity code) legitimately uses both digits 1-9 and letters, which [1-9A-Z] allows for
- A structurally valid GSTIN with an incorrect checksum character still passes, since checksum math isn't performed by regex
- State codes above 37 (the current max as of recent additions) still match numerically even if not yet a real state code
Limitations
- Does not recompute or verify the checksum digit, which uses a modulus-36 algorithm regex cannot express
- Does not confirm the embedded PAN portion is a real, issued PAN
- Cannot verify the GSTIN is active or belongs to the claimed business (requires the GSTN portal/API)
- Assumes the fixed 'Z' convention holds; any future scheme changes would require updating the 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 gstinRegex = /^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z]{1}[1-9A-Z]{1}Z[0-9A-Z]{1}$/;
console.log(gstinRegex.test('22AAAAA0000A1Z5')); // trueCommon Mistakes
Believing this regex confirms the GSTIN is active and registered
Fix: Call the GSTN public search API (or a KYC provider) after format validation for authoritative status
Forgetting the fixed literal 'Z' at position 14 and using [A-Z] there instead
Fix: Keep the literal Z; it is a reserved constant in the current GSTIN scheme, not a variable field
Allowing lowercase GSTINs by adding an 'i' flag
Fix: Real GSTINs are always uppercase; uppercase user input before validating rather than loosening the pattern
Performance Notes
- All character classes have fixed counts, so the engine matches in linear time with no backtracking
- The literal 'Z' anchor mid-pattern lets the engine fail fast on the majority of malformed 15-character strings
- Compile the regex once at module load time since GSTIN validation is often run per-row over large vendor datasets
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.