Regex for Beginners: 8 Patterns You Will Actually Use
Eight practical regular expressions for mobile numbers, dates, PIN codes, PAN, quotes and more, each with a sample and its real result, plus the mistakes to watch for.
How to read this list
Most people meet regular expressions (regex) when they need to pull something out of a pile of text: phone numbers from an export, dates from a log, postal codes from addresses. You do not need the whole language for that. A small set of building blocks covers a large share of everyday jobs, and the rest you can look up when you need it.
Every pattern below was run in the regex tester against a sample line, and the results shown are what it returns. To reproduce one, type the pattern on the first line, then a line containing only ---, then the text. The tester uses the JavaScript engine, applies the global flag so you get every match, and lists the full matched text. Keep three limits in mind: matching is case-sensitive, there is no way to switch on other flags, and it lists matches only, so it cannot replace text.
The building blocks, briefly
\d is a digit, \w is a letter, digit or underscore, \s is whitespace. {4} means exactly four, {2,} means two or more, + means one or more. [6-9] is any one character from that range, and [^"] is any character except a double quote. \b is a word boundary: the edge between a word character and a non-word character. Everything below is made from these.
Pattern 1: a four-digit number, without matching part of a longer one
Pattern: \b\d{4}\b
Sample text: Order 12345 shipped in 2026, ref 7788
Result: 2 matches, 2026 and 7788. Without the \b markers, the plain pattern \d{4} returns 3 matches, because it finds 1234 inside 12345. This is the most common beginner mistake: forgetting that a pattern matches anywhere inside a longer string unless you anchor it.
Pattern 2: an Indian mobile number
Pattern: \b[6-9]\d{9}\b
Sample text: Call 9876543210 or 5123456789 or 98765432101 or 8123456780
Result: 2 matches, 9876543210 and 8123456780. The number starting with 5 is rejected, and the 11-digit number is rejected by the boundaries. This checks the shape only: ten digits starting with 6 to 9. It cannot tell you whether a number is in service, and it will not match numbers written with spaces, dashes or a +91 prefix. Strip those first or write a pattern that allows them.
Pattern 3: a date written dd/mm/yyyy
Pattern: \b\d{2}/\d{2}/\d{4}\b
Sample text: Paid on 04/11/2026 and 31/12/2025; 4/1/2026 is skipped; 99/99/2026 passes
Result: 3 matches, including 99/99/2026. The pattern checks layout, not meaning, so impossible dates get through. The single-digit date 4/1/2026 is skipped because the pattern demands two digits. Use regex to find date-shaped text, then let a date library decide whether it is a real date.
Pattern 4: runs of extra spaces
Pattern: \s{2,}
Sample text: Total due: Rs. 500 now
Result: 2 matches, a run of two spaces and a run of three. This is useful for finding sloppy spacing in pasted text. Because \s includes tabs and line breaks, a blank line between paragraphs will also match. The tester only shows you the problem spots; you need an editor with find-and-replace to fix them.
Pattern 5: an email-shaped string
Pattern: [\w.+-]+@[\w-]+\.[\w.-]+
Sample text: Mail asha.k+bills@example.co.in or help@site.com. Not me@ or @handle
Result: 2 matches, asha.k+bills@example.co.in and help@site.com.. Look closely at the second one: the full stop that ends the sentence was swallowed, because the final part of the pattern allows dots. This is a good illustration of why you should not use regex to decide whether an email address is valid. The real rules are far more involved than any short pattern. A pattern like this is fine for pulling candidates out of text, and you should expect to trim the edges. The only reliable check for an address is to send a message to it.
Pattern 6: a PAN-style identifier
Pattern: \b[A-Z]{5}\d{4}[A-Z]\b
Sample text: PAN ABCDE1234F, bad ABCD12345F, lower abcde1234f
Result: 1 match, ABCDE1234F. A PAN is written as five letters, four digits and one letter, and the pattern encodes that layout. The malformed value with four letters is rejected, and so is the lower-case one, since the tester is case-sensitive. If your data may contain lower-case letters, write [A-Za-z] in place of [A-Z]. Matching the layout does not prove the PAN is issued to anyone.
Pattern 7: a six-digit PIN code
Pattern: \b[1-9]\d{5}\b
Sample text: Pune 411001, Delhi 110001, bad 011001, long 4110011
Result: 2 matches, 411001 and 110001. Indian PIN codes have six digits and do not begin with 0, which is what [1-9] in the first position expresses. The value starting with 0 and the seven-digit value are both rejected. Again, this tells you the shape is plausible, not that the code exists.
Pattern 8: text between quotes, and the greedy trap
Two patterns, one sample: Say "hello" and "bye" now
".*"returns 1 match:"hello" and "bye". The.*is greedy, so it runs to the last quote on the line."[^"]*"returns 2 matches:"hello"and"bye". Saying "any character except a quote" stops the match at the next quote.
The same idea works for brackets, tags and delimiters. When a pattern grabs far more than you wanted, replace .* with a negated class such as [^"]*, or use the lazy form .*?.
A routine for writing a pattern that works
- Collect three sample lines that should match and three that should not, including awkward ones.
- Start with the simplest pattern that matches the first good line. Run it.
- Add one piece at a time. After each change, check that the good lines still match and see whether a bad line has started to match.
- Add boundaries (
\b) or^and$anchors once the core works. Note that in the tester,^and$refer to the start and end of the whole text, so a pattern like^\d+$finds nothing in two lines of digits. - Prefer specific classes such as
[0-9]or[^"]over a loose.*.
Matches come back one per line, so if the same value appears many times in your text you can paste the output into the remove duplicate lines tool to get a unique list. It keeps the first copy of each line and treats upper and lower case as different. A related idea is the slug generator: its rule is a regex in spirit, replacing every run of characters outside a to z and 0 to 9 with one hyphen, which is the same thing the pattern [^a-z0-9]+ describes.
Limits and what this does not cover
- The tester shows whole matches only. It does not list capture groups, does not replace text, and offers no flags, so case-insensitive matching has to be written out by hand with classes like
[Hh]. - It uses JavaScript regex. Other languages differ in details, so a pattern that works here may need small changes in Python, Java or a database. Test it in the real environment before relying on it.
- Regex checks shape, not truth. Phone numbers, dates, PAN and PIN codes can all look right and still be wrong.
- Some patterns with nested repeats can run very slowly on long, nearly-matching text. If your browser tab freezes, simplify the pattern.
- Do not paste confidential data such as real PAN numbers into any online tool you do not control. Use made-up samples while you build the pattern.