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 | — |