Regular expressions (regex) are one of the most powerful tools in a developer's toolkit. Whether you're validating forms, parsing log files, searching through code, or extracting data from messy text โ regex gets it done faster than anything else.
But let's be honest: regex has a steep learning curve. Those cryptic patterns like ^[\\w.-]+@[\\w.-]+\\.\\w{2,}$ look like line noise. The good news? Once you understand the building blocks, it all clicks into place.
This guide covers everything you need to know: from basic characters all the way to advanced lookarounds, with examples you can test right now using our free online regex tester.
What Is a Regular Expression?
A regular expression is a sequence of characters that forms a search pattern. Think of it as a mini programming language for string matching. You can use regex to:
- Validate โ check if input matches a format (email, phone, password strength)
- Extract โ pull specific data from text (emails from a page, IDs from logs)
- Replace โ find and replace text based on patterns
- Split โ break strings into parts at pattern boundaries
Regular expressions are supported in virtually every programming language โ JavaScript, Python, Java, PHP, Go, Ruby, and more โ with only minor syntax variations.
Regex Syntax Basics
Literal Characters
Most characters in a regex match themselves. The pattern cat matches the string "cat" wherever it appears.
Pattern: cat
Matches: "cat" โ "concatenate" โ "scatter" โ
No match: "dog" โ "cot" โ
Metacharacters
These special characters have meaning beyond their literal value and need escaping with \\ to match literally:
| Char | Meaning |
|---|---|
. | Any character except newline |
^ | Start of string / line |
$ | End of string / line |
* | Zero or more of preceding element |
+ | One or more of preceding element |
? | Zero or one (optional) of preceding element |
{} | Exact count / range quantifier |
[] | Character class (one of) |
() | Group / capture |
| | OR operator (alternation) |
\\ | Escape next character / shorthand class |
Character Classes
Character classes match one character from a set:
| Pattern | Meaning | Example |
|---|---|---|
[abc] | a, b, or c | Matches "a" in "apple" |
[a-z] | Any lowercase letter | Matches "t", "e", "s", "t" in "test" |
[0-9] | Any digit | Matches "4" and "2" in "v4.2" |
[^abc] | NOT a, b, or c | Matches "x" in "axbxc" |
Shorthand Character Classes
| Shorthand | Equals | Matches |
|---|---|---|
\\d | [0-9] | A digit |
\\w | [a-zA-Z0-9_] | A word character (letter, digit, underscore) |
\\s | [ \\t\\n\\r\\f\\v] | A whitespace character |
\\D | [^0-9] | NOT a digit |
\\W | [^a-zA-Z0-9_] | NOT a word character |
\\S | [^ \\t\\n\\r\\f\\v] | NOT whitespace |
Example: \\d{3}-\\d{4} matches phone number segments like 555-1234.
Quantifiers
Quantifiers specify how many times the preceding element must appear:
| Quantifier | Meaning | Example |
|---|---|---|
* | Zero or more | ab*c matches "ac", "abc", "abbc" |
+ | One or more | ab+c matches "abc", "abbc" but not "ac" |
? | Zero or one | ab?c matches "ac", "abc" but not "abbc" |
{3} | Exactly 3 | \\d{3} matches "555" |
{2,4} | 2 to 4 | \\d{2,4} matches "55", "555", "5555" |
{3,} | 3 or more | \\d{3,} matches "555", "5555", ... |
Greedy vs Lazy Matching
By default, quantifiers are greedy โ they match as much as possible. Adding a ? after the quantifier makes it lazy, matching as little as possible.
String: <b>bold</b><i>italic</i>
Greedy: <.+> โ matches "<b>bold</b><i>italic</i>" (the whole thing)
Lazy: <.+?> โ matches "<b>" (just the first tag)
This is one of the most common sources of bugs in regex. When extracting HTML tags, comments, or any delimited content, always use lazy quantifiers unless you specifically want the greedy behavior.
Anchors
Anchors don't match characters โ they match positions within the string:
| Anchor | Meaning |
|---|---|
^ | Start of string (or line in multiline mode) |
$ | End of string (or line in multiline mode) |
\\b | Word boundary (start or end of a word) |
\\B | NOT a word boundary |
Example: ^hello matches "hello" only at the beginning of the string. world$ matches "world" only at the end. \\bcat\\b matches "cat" as a whole word but not in "catalog".
Alternation (OR)
The pipe | acts as an OR operator:
cat|dog โ matches "cat" or "dog"
gray|grey โ matches both "gray" and "grey"
Mon|Tue|Wed โ matches any of the three
Use parentheses to limit alternation scope: gr(a|e)y matches "gray" and "grey" more precisely.
Groups and Capturing
Capturing Groups ()
Parentheses create capturing groups that extract specific parts of a match:
Pattern: (\\d{3})-(\\d{4})
String: Phone: 555-1234
Match: "555-1234"
Group 1: "555"
Group 2: "1234"
Captured groups can be used in replacement operations:
Find: (\\w+)@(\\w+)
Replace: $1 [at] $2
Result: john@example โ john [at] example
Named Groups
Modern regex engines support named groups for readability:
(?<name>pattern) โ Named capture group
Pattern: (?<area>\\d{3})-(?<num>\\d{4})
Replace: ${area}-${num}
Matches: "555-1234" with named groups "area"="555" and "num"="1234"
Non-Capturing Groups (?:)
Use (?:) when you need grouping but don't need to capture:
Pattern: (?:\\d{3}-)?\\d{4}
Matches: "555-1234" and "1234" โ groups without capturing overhead
Lookahead and Lookbehind (Lookarounds)
Lookarounds are zero-width assertions โ they check for a pattern without including it in the match. These are essential for complex validations.
| Type | Syntax | Example |
|---|---|---|
| Positive lookahead | (?=...) | \\d(?=px) matches digit followed by "px" |
| Negative lookahead | (?!...) | \\d(?!px) matches digit NOT followed by "px" |
| Positive lookbehind | (?<=...) | (?<=\\$)\\d+ matches digits preceded by "$" |
| Negative lookbehind | (?<!...) | (?<!\\$)\\d+ matches digits NOT preceded by "$" |
Practical examples:
# Extract prices (digits preceded by $)
(?<=\\$)\\d+(\\.\\d{2})?
โ "$29.99" matches "29.99", "โฌ29.99" no match
# Password validation (must contain uppercase, digit, special char)
^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,}$
โ "P@ssw0rd!" โ "password" โ
# Find "cat" but not "catalog"
\\bcat\\b
โ "cat" โ "catalog" โ (partial "cat")
Common Regex Patterns Cheat Sheet
| Pattern | Matches |
|---|---|
^[\\w.-]+@[\\w.-]+\\.\\w{2,}$ | Email (basic) |
https?://[\\w./-]+ | URL (basic) |
^\\+?\\d{1,3}[-. ]?\\d{3,14}$ | Phone number |
^\\d{4}-\\d{2}-\\d{2}$ | Date (YYYY-MM-DD) |
^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$ | IPv4 address (basic) |
#([a-fA-F0-9]{6}|[a-fA-F0-9]{3}) | Hex color code |
(?<=\\/\\/)[^\\/]+ | Domain from URL |
\\b\\w{6,}\\b | Words with 6+ characters |
Regex in Popular Programming Languages
JavaScript
// Test if string contains a pattern
/test/i.test("Hello World"); // โ false
/hello/i.test("Hello World"); // โ true (i = case-insensitive)
// Extract matches
"The price is $29.99".match(/\\$\\d+\\.\\d{2}/); // โ ["$29.99"]
// Replace
"hello@example.com".replace(/(\\w+)@(\\w+)/, "$1 [at] $2");
// โ "hello [at] example"
Python
import re
# Test match
re.search(r'hello', 'Hello World', re.I) # โ match object
# Find all matches
re.findall(r'\\d+', 'App v2.5 released in 2026')
# โ ['2', '5', '2026']
# Replace
re.sub(r'(\\w+)@(\\w+)', r'\\1 [at] \\2', 'john@test.com')
# โ 'john [at] test'
PHP
// Test if pattern exists
preg_match('/hello/i', "Hello World"); // โ 1 (true)
// Extract all matches
preg_match_all('/\\d+/', 'App v2.5', $matches);
// $matches[0] = ['2', '5']
// Replace
preg_replace('/(\\w+)@(\\w+)/', '$1 [at] $2', 'john@test.com');
// โ 'john [at] test'
Common Regex Pitfalls and How to Avoid Them
1. Forgetting to Escape Special Characters
To match a literal dot, use \\. not just .. The unescaped dot matches any character โ a.com would match "aXcom" too.
2. Greedy Quantifiers in Wrong Places
This is the #1 regex bug. When extracting content between delimiters, always consider whether you need lazy (*?, +?) or greedy (*, +) matching.
3. Overly Complex Expressions
A 200-character regex is harder to debug than 3 simple ones. Break complex patterns into steps. For email validation, consider using your language's built-in validator instead โ the full email RFC regex is notoriously monstrous.
4. Catastrophic Backtracking
Patterns like (a+)+b can cause catastrophic backtracking on non-matching strings like "aaaaac". The nested quantifiers create exponential states. Avoid (x+)+ and (x*)* patterns.
5. Not Anchoring Your Patterns
\\d{3} matches "555" anywhere in the string. ^\\d{3}$ matches only if the entire string is exactly 3 digits. Always use ^ and $ anchors for validation.
Test Your Regex Patterns
The best way to learn regex is to practice with real-time feedback. Try our free online regex tester โ enter patterns and see matches instantly:
- Real-time highlighting of matched text
- Detailed match group information
- Case sensitivity toggle
- Global and multiline mode support
- All processing runs in your browser โ nothing leaves your device
๐งช Test Your Regex Patterns Now
Free, fast, and private โ no data uploads, instant results.
Open Regex Tester โFrequently Asked Questions
What is a regular expression?
A regular expression (regex) is a sequence of characters that defines a search pattern. It's used for pattern matching within strings โ validating formats like emails and phone numbers, extracting data, finding and replacing text, and splitting strings. Most programming languages and text editors support regular expressions.
How do I test a regular expression online?
You can test regex patterns online for free using Tools VersionMan's Regex Tester. Simply enter your regex pattern, choose your test string, and see real-time match results with highlighted matches, capture groups, and detailed match information โ all processed locally in your browser.
What does \\d+ mean in regex?
In regex, \\d matches any digit (0-9), and the + quantifier means "one or more". So \\d+ matches one or more consecutive digits โ integers of any length like 42, 123, or 9999. This is one of the most commonly used regex patterns.
What's the difference between greedy and lazy matching?
Greedy matching (default) tries to match as much text as possible. Lazy matching, indicated by adding ? after a quantifier (like *? or +?), tries to match as little as possible. For example, <.+> applied to <b>bold</b> matches the entire string greedily, while <.+?> matches just <b>. Choosing the right mode is crucial for accurate pattern matching.
What are regex capture groups?
Capture groups are parts of a regex pattern enclosed in parentheses () that extract specific portions of a match. For example, (\\d{3})-(\\d{4}) applied to "555-1234" captures "555" and "1234" separately. Groups can be referenced by number ($1, $2) or name (?<name>...) for replacement operations. Non-capturing groups (?:...) group without capturing.