| name | regex |
| category | data |
| description | Write, test, and debug regular expressions for pattern matching, search, and text extraction across programming languages. Use when the user asks to match patterns in text, validate input formats (email, URL, IP, phone, date), extract data with capture groups, build search patterns with lookahead or lookbehind, or understand regex syntax differences between PCRE, POSIX, JavaScript, Python, and Rust flavors.
|
| license | MIT |
| metadata | {"author":"zeph","version":"1.0"} |
Regular Expressions Reference
Quick Reference
| Pattern | Matches |
|---|
. | Any character (except newline) |
\d | Digit [0-9] |
\w | Word character [a-zA-Z0-9_] |
\s | Whitespace (space, tab, newline) |
\D, \W, \S | Negated versions |
^ | Start of line |
$ | End of line |
\b | Word boundary |
* | 0 or more |
+ | 1 or more |
? | 0 or 1 (optional) |
{n} | Exactly n |
{n,m} | Between n and m |
[abc] | Character class |
[^abc] | Negated character class |
(...) | Capture group |
(?:...) | Non-capturing group |
a|b | Alternation |
Character Classes
Shorthand Classes
| Class | Equivalent | Matches |
|---|
\d | [0-9] | Digit |
\D | [^0-9] | Non-digit |
\w | [a-zA-Z0-9_] | Word character |
\W | [^a-zA-Z0-9_] | Non-word character |
\s | [ \t\n\r\f\v] | Whitespace |
\S | [^ \t\n\r\f\v] | Non-whitespace |
\h | [ \t] | Horizontal whitespace (PCRE) |
\v | [\n\r\f\v] | Vertical whitespace (PCRE) |
POSIX Classes (use inside [...])
| Class | Matches |
|---|
[:alpha:] | Letters |
[:digit:] | Digits |
[:alnum:] | Letters and digits |
[:upper:] | Uppercase letters |
[:lower:] | Lowercase letters |
[:space:] | Whitespace |
[:punct:] | Punctuation |
[:print:] | Printable characters |
[:graph:] | Visible characters (no space) |
[:xdigit:] | Hex digits [0-9a-fA-F] |
Usage: [[:alpha:]] (double brackets when inside a character class).
Custom Character Classes
[aeiou] # Vowels
[a-z] # Lowercase letters
[A-Z] # Uppercase letters
[0-9] # Digits
[a-zA-Z0-9] # Alphanumeric
[^aeiou] # NOT vowels
[a-z&&[^m-r]] # a-z except m-r (intersection, Java/Rust)
[-.] # Literal hyphen and dot (hyphen first or last)
[\\^] # Literal backslash and caret
Quantifiers
Greedy (match as much as possible)
| Quantifier | Meaning |
|---|
* | 0 or more |
+ | 1 or more |
? | 0 or 1 |
{3} | Exactly 3 |
{2,5} | 2 to 5 |
{2,} | 2 or more |
Lazy (match as little as possible)
Add ? after the quantifier:
| Lazy | Meaning |
|---|
*? | 0 or more (lazy) |
+? | 1 or more (lazy) |
?? | 0 or 1 (lazy) |
{2,5}? | 2 to 5 (lazy) |
Example difference:
Input: <b>bold</b> and <b>more</b>
Greedy: <b>.*</b> matches "<b>bold</b> and <b>more</b>"
Lazy: <b>.*?</b> matches "<b>bold</b>" then "<b>more</b>"
Possessive (no backtracking, PCRE/Java)
Add + after the quantifier: *+, ++, ?+
Possessive quantifiers never give back matched characters, which prevents catastrophic backtracking but may cause the match to fail where greedy would succeed.
Anchors
| Anchor | Matches |
|---|
^ | Start of line (or string with \A) |
$ | End of line (or string with \z / \Z) |
\b | Word boundary |
\B | Non-word boundary |
\A | Start of string (never affected by multiline flag) |
\z | End of string (absolute) |
\Z | End of string (allows trailing newline) |
\bword\b # "word" as a whole word
^line$ # Entire line equals "line"
\Afirst # "first" at the very start of the string
Groups
Capturing Groups
(abc) # Capture group 1
(a)(b)(c) # Groups 1, 2, 3
(a(b)c) # Nested: group 1 = "abc", group 2 = "b"
Named Groups
(?P<name>pattern) # Python, PCRE (also (?<name>pattern) in PCRE2)
(?<name>pattern) # JavaScript, .NET, Rust, Java, PCRE2
Non-Capturing Groups
(?:abc) # Group without capturing
Backreferences
(foo)\1 # Match "foo" followed by "foo" again
(?P<word>\w+)\s+\k<word> # Named backreference (PCRE)
\1, \2, \3 # Numbered backreferences
Lookaround Assertions
Lookaround matches a position without consuming characters (zero-width).
Lookahead
foo(?=bar) # "foo" followed by "bar" (positive lookahead)
foo(?!bar) # "foo" NOT followed by "bar" (negative lookahead)
Lookbehind
(?<=foo)bar # "bar" preceded by "foo" (positive lookbehind)
(?<!foo)bar # "bar" NOT preceded by "foo" (negative lookbehind)
Lookbehind restrictions: in most flavors (PCRE, Python, JavaScript), lookbehind must have a fixed length. Variable-length lookbehind is supported in .NET, Java 13+, and Python's regex module.
Practical Examples
# Password: at least one digit, one uppercase, one lowercase
^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}$
# Number NOT followed by "px"
\d+(?!px)
# Dollar amount
(?<=\$)\d+(\.\d{2})?
# Word between quotes
(?<=")([^"]+)(?=")
Alternation
cat|dog # "cat" or "dog"
(cat|dog) food # "cat food" or "dog food"
colou?r # "color" or "colour"
gr[ae]y # "gray" or "grey"
Flags / Modifiers
| Flag | Name | Effect |
|---|
i | Case insensitive | a matches A |
m | Multiline | ^ and $ match line boundaries |
s | Dotall / single-line | . matches newline |
x | Extended / verbose | Ignore whitespace and # comments |
g | Global | Match all occurrences (not all flavors) |
u | Unicode | Full Unicode matching |
Inline flags (within pattern):
(?i)pattern # Case insensitive
(?im)pattern # Case insensitive + multiline
(?i:pattern) # Scoped to group only
Common Patterns
Email Address (simplified)
[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}
URL
https?://[^\s/$.?#][^\s]*
IPv4 Address
\b(?:\d{1,3}\.){3}\d{1,3}\b
Strict (0-255 per octet):
\b(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\b
IPv6 Address (simplified)
(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}
Date (YYYY-MM-DD)
\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])
Time (HH:MM:SS, 24h)
(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d
Phone Number (US)
(?:\+1[-.\s]?)?(?:\(?\d{3}\)?[-.\s]?)?\d{3}[-.\s]?\d{4}
Hex Color
#(?:[0-9a-fA-F]{3}){1,2}\b
Semantic Version
\bv?(\d+)\.(\d+)\.(\d+)(?:-([\w.]+))?(?:\+([\w.]+))?\b
UUID
[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}
File Path (Unix)
(?:/[\w.-]+)+/?
Whitespace Normalization
\s+ # Match consecutive whitespace (for replacement with single space)
^\s+|\s+$ # Leading or trailing whitespace (for trimming)
Flavor Differences
| Feature | PCRE | JavaScript | Python | Rust | POSIX BRE | POSIX ERE |
|---|
\d | Yes | Yes | Yes | Yes | No | No |
| Named groups | (?P<n>) | (?<n>) | (?P<n>) | (?P<n>) | No | No |
| Lookbehind | Fixed | Fixed (ES2018) | Fixed | No | No | No |
| Backrefs | Yes | Yes | Yes | No | \1 | No |
Possessive ++ | Yes | No | No | No | No | No |
Atomic (?>) | Yes | No | No | Yes | No | No |
Unicode \p{L} | Yes | Yes (u flag) | Yes | Yes | No | No |
\b | Yes | Yes | Yes | Yes | No | No |
Multiline . | (?s) | s flag | re.DOTALL | (?s) | N/A | N/A |
Key flavor notes
- Rust (
regex crate): no backreferences, no lookaround (use fancy-regex for those). Guaranteed linear time.
- JavaScript: lookbehind added in ES2018 (modern browsers). No possessive quantifiers or atomic groups.
- Python:
re module has fixed-length lookbehind. regex module (third-party) supports variable-length lookbehind.
- POSIX BRE: requires escaping
(, ), {, } — they are literal without backslash. Used by grep (default), sed.
- POSIX ERE:
(, ), {, } are special without backslash. Used by grep -E, awk, sed -E.
Testing Strategies
echo "test123" | grep '[0-9]\+'
echo "test123" | grep -E '[0-9]+'
echo "test123" | grep -P '\d+'
echo "2024-01-15" | sed -E 's/([0-9]{4})-([0-9]{2})-([0-9]{2})/\3\/\2\/\1/'
python3 -c "import re; print(re.findall(r'\d+', 'abc123def456'))"
Performance Tips
- Avoid catastrophic backtracking:
(a+)+b on "aaaaaac" causes exponential time
- Use possessive quantifiers (
++) or atomic groups ((?>...)) when available
- Anchored patterns (
^...$) are faster than unanchored
- Character classes
[aeiou] are faster than alternation a|e|i|o|u
- Avoid
.* at the start of a pattern; use a more specific prefix
- Pre-compile regex objects when matching in a loop (all languages)
- Use non-capturing groups
(?:...) when you do not need the captured text
- Rust's
regex crate guarantees O(n) matching; if you need backreferences, use fancy-regex but be aware of potential exponential time
Important Notes
- Always use raw strings in programming languages to avoid double-escaping: Python
r"\d+", Rust r"\d+"
\b matches a position between a word character and a non-word character, not a character itself
. does not match \n by default; enable dotall/single-line mode (s flag) if needed
^ and $ match start/end of string by default; enable multiline mode (m flag) for line boundaries
- In character classes, most special characters lose their meaning:
[.] matches a literal dot
- Hyphen in character class must be first, last, or escaped:
[a-z] is a range, [-az] includes literal -
- Caret
^ negates a character class only when it is the first character: [^abc]
- Always test regex against edge cases: empty strings, very long inputs, Unicode, special characters