JavaScript RegExp Patterns

Regular expression patterns are built from characters, character classes, quantifiers, anchors, and groups. Understanding these building blocks lets you construct powerful search patterns.

Character Classes

Character classes match any one character from a set. Use square brackets to define a class. A range can be specified with a hyphen.

Character Classes
// Match specific characters
console.log(/[aeiou]/.test('hello')); // true (matches 'e')
console.log(/[aeiou]/.test('gym'));    // false

// Character ranges
console.log(/[a-z]/.test('Hello'));  // true (matches 'e')
console.log(/[A-Z]/.test('hello'));  // false
console.log(/[0-9]/.test('abc123')); // true (matches '1')

// Negated character class
console.log(/[^0-9]/.test('123'));   // false (no non-digit)
console.log(/[^0-9]/.test('12a3')); // true (found 'a')

// Predefined classes
console.log(/\d/.test('abc3'));  // true (\d = digit)
console.log(/\w/.test('$$$'));   // false (\w = word char)
console.log(/\s/.test('hello world')); // true (\s = whitespace)
ClassMatchesEquivalent
[abc]Any of a, b, or c
[^abc]Any character NOT a, b, or c
[a-z]Any lowercase letter
[0-9]Any digit\d
\dAny digit[0-9]
\DAny non-digit[^0-9]
\wAny word character[a-zA-Z0-9_]
\WAny non-word character[^a-zA-Z0-9_]
\sAny whitespace[ \t\n\r\f\v]
\SAny non-whitespace[^ \t\n\r\f\v]
.Any character (except newline)

Quantifiers

Quantifiers specify how many times a character, group, or character class must appear for a match.

Quantifiers
// + : One or more
console.log('aaa'.match(/a+/)[0]); // 'aaa'
console.log(/\d+/.test('no digits')); // false

// * : Zero or more
console.log('b'.match(/ab*/)[0]);   // 'b' — wait, no match
console.log('ab'.match(/ab*/)[0]);  // 'ab'
console.log('abbb'.match(/ab*/)[0]); // 'abbb'

// ? : Zero or one (optional)
console.log('color'.match(/colou?r/)[0]);  // 'color'
console.log('colour'.match(/colou?r/)[0]); // 'colour'

// {n} : Exactly n times
console.log(/\d{3}/.test('12'));   // false
console.log(/\d{3}/.test('123'));  // true

// {n,m} : Between n and m times
console.log('12345'.match(/\d{2,4}/)[0]); // '1234'

// {n,} : At least n times
console.log(/a{2,}/.test('a'));    // false
console.log(/a{2,}/.test('aaa')); // true

Anchors

Anchors do not match characters; they match positions. The caret (^) matches the start, and the dollar sign ($) matches the end of a string (or line in multiline mode).

Anchors and Word Boundaries
// ^ : Start of string
console.log(/^Hello/.test('Hello World'));  // true
console.log(/^Hello/.test('Say Hello'));    // false

// $ : End of string
console.log(/World$/.test('Hello World'));  // true
console.log(/World$/.test('World Hello'));  // false

// ^ and $ together: exact match
console.log(/^\d{5}$/.test('12345'));  // true
console.log(/^\d{5}$/.test('123456')); // false

// \b : Word boundary
console.log(/\bcat\b/.test('the cat sat'));   // true
console.log(/\bcat\b/.test('concatenate'));   // false

Groups and Alternation

Parentheses create groups that can capture matched text. The pipe character (|) provides alternation, matching either the pattern on the left or the right.

Groups and Alternation
// Capturing groups
const datePattern = /(\d{4})-(\d{2})-(\d{2})/;
const match = '2024-01-15'.match(datePattern);
console.log(match[0]); // '2024-01-15'
console.log(match[1]); // '2024'
console.log(match[2]); // '01'
console.log(match[3]); // '15'

// Alternation
const petPattern = /cat|dog|fish/;
console.log(petPattern.test('I have a dog')); // true
console.log(petPattern.test('I have a bird')); // false

// Group with alternation
const colorPattern = /colou?r (red|blue|green)/;
console.log(colorPattern.test('color red'));   // true
console.log(colorPattern.test('colour blue')); // true

// Non-capturing group (?:)
const result = 'foobar'.match(/(?:foo)(bar)/);
console.log(result[1]); // 'bar' (only bar is captured)

Escaping Special Characters

Characters like . * + ? ^ $ { } [ ] ( ) | \ have special meaning in regex. To match them literally, escape them with a backslash.

Escaping Special Characters
// Matching a literal dot
console.log(/3.14/.test('3X14'));   // true (. matches any char)
console.log(/3\.14/.test('3X14')); // false (\. matches literal dot)
console.log(/3\.14/.test('3.14')); // true

// Matching parentheses
console.log(/\(hello\)/.test('(hello)')); // true

// Matching a dollar sign
console.log(/\$\d+/.test('Price: $50')); // true

// In constructor, double escape
const pattern = new RegExp('\\d+');
console.log(pattern.test('123')); // true
📝 Note: When using the RegExp constructor with a string, you must double-escape backslashes. For example, '\\d' in the constructor is equivalent to /\d/ in literal notation.
Common Practical Patterns
// Email (basic)
const email = /^[\w.-]+@[\w.-]+\.[a-zA-Z]{2,}$/;
console.log(email.test('user@example.com'));  // true
console.log(email.test('user@.com'));          // false

// Phone number (US format)
const phone = /^\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}$/;
console.log(phone.test('(555) 123-4567')); // true
console.log(phone.test('555-123-4567'));    // true
console.log(phone.test('5551234567'));      // true

// URL (basic)
const url = /^https?:\/\/[\w.-]+\.[a-zA-Z]{2,}/;
console.log(url.test('https://example.com')); // true
Exercise:
Which quantifier means 'zero or more' occurrences?
Try it YourselfCtrl+Enter to run
Click Run to see the output here.