🧩 Developer & Validation Guide

Regex Tester Guide: Patterns, Flags & Indian Phone/Email Validation (2026)

📅 June 2026⏱ 10 min read✍️ ToolLoom Editorial

Regular expressions look like line noise until they click — then they become the fastest way to validate, search, and extract text in any codebase. This guide breaks down flags, capture groups, greedy vs lazy matching, and gives you ready-to-use patterns for validating Indian phone numbers, PAN, GST numbers, and email addresses.

📋 In This Article
  1. What is a regular expression?
  2. Regex flags explained — g, i, m, s
  3. Capture groups — extracting matched data
  4. Greedy vs lazy matching
  5. Indian-specific regex patterns — phone, PAN, GST
  6. Email validation regex — the practical pattern
  7. Quick regex cheat sheet
  8. 5 regex mistakes developers make
  9. Frequently asked questions

What Is a Regular Expression?

A regular expression (regex) is a sequence of characters that defines a search pattern. Instead of searching for an exact string, regex lets you describe a pattern — "any 10 digits," "an email-like structure," "a word starting with capital A" — and match all text fitting that description.

Form Validation
Validating email addresses, phone numbers, PAN/Aadhaar formats, and password strength requirements before form submission.
🔍
Search & Extract
Pulling specific data — dates, prices, IDs — out of large unstructured text like logs, scraped HTML, or PDF exports.
🔄
Find & Replace
Bulk text transformations in code editors (VS Code, Sublime) — renaming variables, reformatting dates, cleaning data.
🛡️
Input Sanitisation
Stripping or rejecting unwanted characters from user input to prevent injection attacks and malformed data.

Regex Flags Explained — g, i, m, s

Flags modify how a regex pattern behaves during matching. They're appended after the closing slash in JavaScript syntax: /pattern/flags.

FlagNameEffectExample
gGlobalFinds ALL matches, not just the first/cat/g on "cat cat cat" finds 3 matches
iCase-insensitiveIgnores letter case during matching/cat/i matches "Cat", "CAT", "cAt"
mMultiline^ and $ match start/end of each line, not whole stringUseful for matching line-by-line in multi-line text
sDotAll. matches newline characters too (normally it doesn't)Useful for matching across line breaks
uUnicodeEnables full Unicode matching, including emoji and non-Latin scriptsImportant when working with Hindi or other Indian language text
💡

Flags combine freely: /pattern/gi means "find all matches, case-insensitive." This is the most commonly used combination for search-and-replace operations across an entire document.

Capture Groups — Extracting Matched Data

Capture groups, denoted by parentheses (), let you extract specific parts of a match rather than just confirming a pattern exists.

Basic capture group example
Pattern: (\d{3})-(\d{4})
Input:   "555-1234"
Group 1: "555"
Group 2: "1234"
Named capture groups — more readable
Pattern: (?<area>\d{3})-(?<number>\d{4})
Input:   "555-1234"
Result:  { area: "555", number: "1234" }

Named groups, using the (?<name>...) syntax, are especially useful in production code — referencing match.groups.area is far more readable than remembering that group 1 means "area code."

Practical use: Extracting structured data from an Indian invoice number like "INV-2026-00451" using pattern INV-(?<year>\d{4})-(?<seq>\d+) instantly gives you the year and sequence number as separate, named values.

Greedy vs Lazy Matching

This single concept trips up more developers than almost anything else in regex. Quantifiers (*, +, {n,m}) are greedy by default — they match as much text as possible.

Greedy vs lazy on the same input
Input:  "<a><b>"
Greedy: <.*>   → matches "<a><b>" (entire string)
Lazy:   <.*?>  → matches "<a>" (stops at first >)
QuantifierTypeBehaviour
*GreedyMatches as much as possible (0 or more)
*?LazyMatches as little as possible (0 or more)
+GreedyMatches as much as possible (1 or more)
+?LazyMatches as little as possible (1 or more)
⚠️

This is the #1 cause of broken HTML/XML regex. Trying to match individual tags with <.*> across multiple tags greedily consumes everything between the first < and the LAST >. Use <.*?> for lazy matching, or better — use a proper HTML parser, not regex, for HTML.

Indian-Specific Regex Patterns — Phone, PAN, GST

FormatRegex PatternMatches
Indian mobile (10-digit)^[6-9]\d{9}$9876543210
Indian mobile with +91^(\+91[\-\s]?)?[6-9]\d{9}$+91 9876543210, 919876543210
PAN card^[A-Z]{5}\d{4}[A-Z]{1}$ABCDE1234F
GST number^\d{2}[A-Z]{5}\d{4}[A-Z]{1}\d[Z][A-Z\d]$27AAACR5055K1Z3
PIN code (6-digit)^[1-9]\d{5}$400001, 110001
IFSC code^[A-Z]{4}0[A-Z0-9]{6}$SBIN0001234
Aadhaar (12-digit, basic)^\d{4}\s?\d{4}\s?\d{4}$1234 5678 9012
🚨

Format validation ≠ existence verification. These patterns confirm a string follows the correct structural format — they do NOT verify the PAN, GST number, or Aadhaar is actually issued or active. For legal/financial use cases, always verify against the official government database (Income Tax e-filing portal for PAN, GSTN portal for GST, UIDAI for Aadhaar) in addition to format checks.

Email Validation Regex — The Practical Pattern

Practical email regex (good enough for most forms)
^[\w.+-]+@[\w-]+\.[a-zA-Z]{2,}$

This pattern matches the vast majority of real-world email addresses — letters, numbers, dots, plus signs, and hyphens in the local part; a domain with at least one dot; and a TLD of 2+ letters.

⚠️

Fully RFC 5322 compliant email validation is famously complex — the "official" regex is hundreds of characters long and still has edge cases. For production systems, combine basic regex validation (catches obvious typos) with an actual verification email (confirms the address truly exists and is accessible) — regex alone cannot guarantee deliverability.

🧩 Test Your Regex Pattern Live — Free

Live match highlighting, capture groups, all flags supported, and a full cheat sheet. Uses the native JavaScript regex engine — test patterns exactly as they'll behave in production.

Open Regex Tester →

Quick Regex Cheat Sheet

SymbolMeaningExample Use
\dAny digit (0-9)Matching numbers
\wWord character (letters, digits, underscore)Matching identifiers, usernames
\sWhitespace (space, tab, newline)Matching gaps between words
^Start of string (or line, with m flag)Anchoring pattern to the beginning
$End of string (or line, with m flag)Anchoring pattern to the end
{n,m}Between n and m repetitions\d{10} matches exactly 10 digits
[abc]Character class — matches a, b, or c[6-9] matches any digit 6 through 9
(?:...)Non-capturing groupGroups without creating a capture reference
(?=...)Positive lookaheadMatch only if followed by a pattern
|OR — alternationcat|dog matches "cat" or "dog"

5 Regex Mistakes Developers Make

MistakeWhy It's a ProblemFix
Using regex to parse HTML/XMLHTML is not a regular language — nested tags break regex matching unpredictablyUse a proper parser (DOMParser, BeautifulSoup, cheerio) for HTML/XML
Forgetting to escape special charactersCharacters like . ( ) [ ] have special meaning; unescaped they don't match literallyEscape with backslash: \. \( \) to match the literal character
Overcomplicating email validationTrying to write a "perfect" RFC-5322 regex wastes time and still has edge casesUse a practical pattern plus actual email verification, not regex alone
Not testing against edge casesA pattern that works on 5 test inputs may fail on unicode, empty strings, or unusual formatsTest with edge cases: empty input, very long input, special characters, unicode
Catastrophic backtracking with nested quantifiersPatterns like (a+)+ can cause exponential time complexity on certain inputs, freezing the applicationAvoid nested quantifiers on the same character class; test performance on malicious-looking input

Frequently Asked Questions

A regular expression is a sequence of characters that defines a search pattern. It is used for string matching, validation, search-and-replace operations, and text parsing across virtually all programming languages — validating emails, phone numbers, extracting data from text, and find-replace in code editors.
g (global) finds all matches, not just the first. i (case-insensitive) ignores letter case. m (multiline) makes ^ and $ match start/end of each line. s (dotAll) makes . match newline characters too. Flags can be combined, e.g. 'gi' for global case-insensitive search.
Capture groups, denoted by parentheses (), let you extract specific parts of a match. (\d{3})-(\d{4}) on '555-1234' captures '555' as group 1 and '1234' as group 2. Named groups use (?<name>...) syntax for more readable extraction.
A practical email regex: ^[\w.+-]+@[\w-]+\.[a-zA-Z]{2,}$. This matches most common email formats. Fully RFC-5322 compliant validation is extremely complex — for production use, combine basic regex validation with actually sending a verification email.
For Indian 10-digit mobile numbers starting with 6-9: ^[6-9]\d{9}$. To allow optional +91 country code: ^(\+91[\-\s]?)?[6-9]\d{9}$. This validates the format but doesn't verify the number is active or assigned to a real subscriber.
Greedy quantifiers (*, +, {n,m}) match as much text as possible. Lazy quantifiers (*?, +?, {n,m}?) match as little as possible. On '<a><b>', the pattern <.*> greedily matches the entire string, while <.*?> lazily matches just '<a>'.

More from ToolLoom

About ToolLoom

ToolLoom builds free developer and productivity tools for Indian students, professionals, and creators. Found a bug or want a feature in the Regex Tester? Email us at contact@toolloom.in