Examples:
/ / g
Flags:
0 matches

      

No matches yet. Edit the pattern or test string above.

Supports $1, $<name>, $&

      
Regex cheatsheet - click any token to insert into the pattern

Character classes

digit (0-9) non-digit word char non-word whitespace non-whitespace any char (except newline) any of a, b, c none of a, b, c range

Anchors

start of string/line end of string/line word boundary non-boundary

Quantifiers

0 or more (greedy) 1 or more 0 or 1 exactly 3 2 to 5 lazy (non-greedy)

Groups & lookaround

capturing group non-capturing named group lookahead negative lookahead lookbehind negative lookbehind alternation

How JavaScript Regular Expressions Work

A regular expression is a small language for describing patterns inside text. JavaScript exposes regex through the RegExp object and the literal syntax /pattern/flags. When you compile a pattern, the engine builds a state machine that walks through your input character by character looking for sequences that satisfy the rules you wrote. The regex tester above runs entirely in your browser using the same native RegExp engine your applications already rely on, so the matches you see are exactly the matches your code will see at runtime.

Patterns are made of literal characters and metacharacters. A literal like the letter a matches the letter a. Metacharacters such as ., *, +, ?, (, ), [, ], {, }, |, ^, $ and \ have special meanings. Use a backslash to escape them when you want the literal character, for example \. for a real period. Character classes like \d, \w, and \s are convenient shortcuts for digits, word characters, and whitespace. Custom classes such as [a-zA-Z0-9_] let you express ranges and unions explicitly.

Flags Change How Patterns Match

JavaScript supports six flags. The global flag g tells the engine to find every match instead of stopping at the first one, which is what you usually want when scanning text. The i flag makes matching case-insensitive. The m flag changes the meaning of ^ and $ so they anchor to the start and end of each line rather than the whole string. The s flag (dotAll) lets . match newline characters, which is useful for patterns that span multiple lines. The u flag turns on full Unicode mode and unlocks features like \p{...} property escapes and surrogate pair handling. The y (sticky) flag forces matching to start exactly at lastIndex, which is helpful when you implement your own tokenizer.

Capture Groups and Backreferences

Parentheses around part of a pattern create a capturing group. After a successful match, each group is numbered from one in the order its opening parenthesis appears. Use (?:...) when you want grouping without the bookkeeping cost of a capture, and use (?<name>...) to give a group a name so you can reference it as match.groups.name. Inside a replacement string, $1 through $9 refer to numbered groups, $<name> refers to a named group, $& is the entire match, and $$ produces a literal dollar sign. The replace panel above accepts all of these tokens because it runs String.prototype.replace directly.

Common Pitfalls

Greedy quantifiers are the source of more regex bugs than any other feature. By default .* consumes as much as possible before backtracking, which means a pattern like <.*> against the string <a><b> matches the whole input rather than just the first tag. Adding a question mark, as in <.*?>, switches the quantifier to lazy and matches only up to the first closing bracket. When in doubt, prefer a more specific class such as [^>]* over a broad .*.

Anchors are another stumbling block. Without ^ or $ a pattern can match anywhere in the input, which sometimes finds a substring you did not intend. Use anchors when you want to validate an entire field. Be aware that with the m flag the anchors apply per line, so they are not the same as start-of-string and end-of-string. The literal start and end of input are \A and \z in some flavors, but JavaScript does not support those, so to validate a whole string use ^...$ without the multiline flag, or wrap the pattern in something like ^(?:...)$.

Email and URL validation deserve special caution. The pattern \b\w+@\w+\.\w+\b is great for finding probable email addresses inside free text, but it does not satisfy the official RFC. Trying to match the full RFC with regex produces a famously enormous expression. For form validation prefer the browser's type="email" input or a small library, and reserve regex for the cases where loose matching is acceptable.

Frequently Asked Questions

Does the regex tester send my pattern to a server?

No. Everything runs locally in your browser using the built-in JavaScript RegExp engine. Your pattern, your test string, and any replacement output never leave your device. That makes it safe to paste server logs, configuration files, or any other content you would not want to upload to a third-party service.

Why do I see different results compared to PCRE, Python, or Java?

This tool implements the JavaScript flavor of regular expressions. Most basic syntax is shared across flavors, but there are real differences. JavaScript does not support possessive quantifiers, \A, \z, or atomic groups. Lookbehind has only landed in modern engines and may behave differently from PCRE. Always test against the regex engine of the language you actually plan to deploy with.

What is the difference between greedy and lazy quantifiers?

A greedy quantifier consumes as much input as it can before letting the engine try the rest of the pattern. A lazy quantifier, written by adding ? after the quantifier, consumes as little as possible. So a.*b on aXXbYYb matches the whole string up to the last b, while a.*?b matches only aXXb. Lazy quantifiers are often the right choice when you are extracting tokens that have a clear delimiter.

How do named capture groups work?

Use the syntax (?<name>pattern) to give a capture group a label. After a match the group is available as match.groups.name in addition to its numbered position. In a replacement string the same group can be referenced as $<name>. Names must be valid JavaScript identifiers and must be unique within a pattern.

Why does the global flag affect my results?

Without the g flag String.matchAll throws an error and String.replace only replaces the first occurrence. With the flag set the engine finds every non-overlapping match in the input. The tester uses matchAll when g is on so you can see every hit at once, and falls back to a single exec call otherwise. If you expect to see multiple matches but only see one, check that g is enabled.

What does the sticky flag actually do?

The y flag forces the engine to match starting exactly at the lastIndex property of the regex. If a match cannot start at that position the call returns null instead of scanning forward. Sticky regexes are valuable when you write a hand-rolled tokenizer because they let you advance through input one token at a time without resetting state. Most everyday tasks do not need this flag.

Can I share my pattern with a teammate?

Use the copy buttons above the test string. The first copies your regex as a JavaScript literal in the form /pattern/flags ready to paste into source code. The second copies the raw pattern as a plain string, which is convenient for languages like Python or Java that accept the pattern separately from the flags. Combine that with a screenshot of the highlighted matches if you want to explain a tricky example to a coworker.