JavaScript Regex Syntax Reference

The definitive guide to Regular Expressions in JavaScript. Learn RegExp literals, methods, flags, and modern ES2018+ features.

Creating Regular Expressions

Literal Syntax (Preferred)
const pattern = /hello/gi;
const emailRegex = /^[\w-]+@[\w-]+\.[a-z]{2,}$/i;
Constructor Syntax (Dynamic patterns)
const pattern = new RegExp('hello', 'gi');
// Useful when pattern comes from user input:
// Escape special characters to make input safe for regex
const dynamicRegex = new RegExp(searchTerm, 'gi');

Regex Flags

gGlobal - Find ALL matches, not just the first one.
iCase-Insensitive - "abc" matches "ABC", "Abc", etc.
mMultiline - ^ and $ match start/end of each LINE, not just the string.
sDotAll (ES2018) - Makes . match newline characters too.
uUnicode - Enable full Unicode support, correct handling of emojis/surrogates.
ySticky - Match only at the current position (lastIndex).

String & RegExp Methods

// TEST - Returns true/false if pattern exists
/hello/.test('hello world') // true

// MATCH - Returns array of matches (or null)
'hello world'.match(/o/g) // ['o', 'o']

// MATCHALL - Iterator of all matches with groups (ES2020)
[...'a1 b2'.matchAll(/(\w)(\d)/g)]
// [{ 0: 'a1', 1: 'a', 2: '1' }, { 0: 'b2', 1: 'b', 2: '2' }]

// REPLACE - Replace matches with string or function
'hello'.replace(/l/g, 'L') // 'heLLo'

// REPLACEALL - Replace all occurrences (ES2021)
'aaa'.replaceAll('a', 'b') // 'bbb'

// SEARCH - Returns index of first match (or -1)
'hello'.search(/l/) // 2

// SPLIT - Split string by pattern
'a,b; c'.split(/[,;]\s*/) // ['a', 'b', 'c']

// EXEC - Returns match with details, advances lastIndex
const re = /(\w+)/g;
re.exec('one two') // ['one', 'one', index: 0, ...]
re.exec('one two') // ['two', 'two', index: 4, ...]

Named Capture Groups (ES2018)

// Define named groups with (?<name>...)
const dateRegex = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const match = dateRegex.exec('2024-01-25');

// Access by name!
console.log(match.groups.year);  // '2024'
console.log(match.groups.month); // '01'
console.log(match.groups.day);   // '25'

// Use in replace with $<name>
'2024-01-25'.replace(dateRegex, '$<month>/$<day>/$<year>')
// '01/25/2024'

JavaScript Regular Expressions: The Complete Guide

JavaScript has robust regular expression support built directly into the language. Unlike some languages where regex is a library feature, JavaScript regex is a first-class citizen with dedicated syntax (regex literals) and deep integration with string methods. This guide covers everything from basic usage to advanced ES2018+ features like named capture groups and lookbehind assertions.

Understanding JavaScript regex is essential for frontend and backend developers alike. From form validation and input parsing on the client to log analysis and data transformation on the server, regex patterns appear throughout modern JavaScript codebases.

Literal vs Constructor: When to Use Each

JavaScript offers two ways to create regular expressions. The literal syntax /pattern/flags is evaluated at parse time and should be used when the pattern is a constant. It is cleaner, avoids escaping issues, and benefits from syntax highlighting in most editors.

The constructor syntax new RegExp(pattern, flags) is evaluated at runtime and is necessary when the pattern is dynamic—for example, when it comes from user input or is constructed programmatically. The catch is that you are passing a string, so backslashes need to be doubled.

When using the constructor with user input, always escape special characters first to prevent regex injection. This makes the string safe to use in a pattern.

Understanding Flags in Depth

The g (global) flag is perhaps the most commonly needed. Without it, methods like match return only the first match, and replace replaces only the first occurrence. With g, you get all matches and all replacements.

The u (unicode) flag is increasingly important in modern applications dealing with emoji and international text. Without it, regex treats strings as sequences of 16-bit code units, which breaks for characters outside the Basic Multilingual Plane (including many emoji). With u, the dot correctly matches a full Unicode code point.

The s (dotAll) flag, added in ES2018, changes the behavior of dot to match newline characters. Without it, dot matches any character except newlines. This flag is essential when matching patterns that span multiple lines, like extracting content between HTML tags.

The y (sticky) flag is specialized but useful for tokenizers and parsers. It forces matching to start exactly at the regex lastIndex property, rather than searching forward for a match. This enables stepping through a string token by token.

Choosing the Right Method

JavaScript provides multiple methods for working with regex, and choosing the right one depends on what you need to accomplish.

The test() method is the simplest—it returns true or false indicating whether the pattern matches. Use it for validation. It is faster than methods that return match details.

The match() method returns an array of matches. Without the g flag, it returns detailed information about the first match including capture groups. With g, it returns an array of all matches but without group details.

The matchAll() method (ES2020) fills the gap: it returns an iterator yielding match objects with full details for every match. The pattern must have the g flag. Convert to array with spread.

The replace() method substitutes matches with a replacement string or the result of a function. The replacement string supports special patterns: $1, $2 for numbered groups, $& for the whole match.

The exec() method is the low-level method on RegExp objects. With the g flag, calling it repeatedly advances through matches (updating lastIndex). This is useful for processing matches in a loop with full control, though matchAll is often cleaner.

Capture Groups and References

Parentheses in a regex create capture groups that save matched content for later reference. The username and domain can be captured in groups 1 and 2 respectively.

Backreferences like \1 refer to captured content within the same pattern. This can match repeated words like "the the". In replacement strings, use $1, $2, etc.

Named capture groups (ES2018) improve readability significantly. Instead of remembering group numbers, you can name them and access captures via match.groups.name.

Non-capturing groups (?:...) provide grouping for quantifiers without capturing. Use when you need to apply a quantifier to multiple characters but do not need to reference the matched content.

Lookahead and Lookbehind

Lookaround assertions match conditions without consuming characters. Positive lookahead (?=...) asserts that what follows matches. Negative lookahead (?!...) asserts that what follows does NOT match.

Lookbehind was added in ES2018. Positive lookbehind asserts what precedes the match. Negative lookbehind asserts what does NOT precede. Note that lookbehind has restrictions in some regex engines.

Common Patterns and Gotchas

Greedy vs lazy matching: by default, * and + are greedy—they match as much as possible. Add ? for lazy matching to match as little as possible.

The lastIndex property on regex objects with g flag maintains state between exec() or test() calls. This can cause unexpected behavior when reusing a regex. Reset with regex.lastIndex = 0 or create a new regex each time.

Be careful with ^ and $ in multiline mode. Without m, they match only start/end of the entire string. With m, they match start/end of each line.

Performance Considerations

Regex performance can vary dramatically based on the pattern. Catastrophic backtracking occurs with certain patterns on certain inputs, causing exponential time complexity. Avoid nested quantifiers on overlapping patterns.

Compiled regex (literals or cached RegExp objects) are faster than creating new RegExp objects repeatedly. If using the constructor in a loop, create the regex outside the loop.

For simple operations, string methods may be faster than regex. string.includes('text') is faster than /text/.test(string) for literal substring checks. Use regex when you need pattern matching, not for simple string operations.