Regular expressions describe text patterns
A regular expression, or regex, is a compact language for searching text. It can match literal characters, alternatives, repeated shapes, boundaries, and captured subparts. Regex appears in editors, validation, log analysis, routing, data cleaning, and programming languages.
There is no single universal regex dialect. This tester uses the browser’s JavaScript implementation defined by ECMAScript. Patterns from PCRE, Python, Java, .NET, Rust, or command-line tools can require changes.
The expression is entered without surrounding slash delimiters. Flags are entered separately, as they are arguments to JavaScript’s RegExp constructor.
Literals and metacharacters
Most ordinary characters match themselves. The pattern cat finds those three consecutive letters. Several characters have special meaning, including ., *, +, ?, ^, $, parentheses, brackets, braces, the vertical bar, and backslash.
Escape a metacharacter with backslash when it should be literal. \. matches a period, while . normally matches almost any single character.
When a regex is also written inside a programming-language string, the string parser may consume backslashes first. A JavaScript string often needs "\\d+" to construct the regex \d+. This tester accepts the regex source directly, so one backslash is enough.
Character classes
Square brackets match one character from a set. [abc] matches a, b, or c. Ranges such as [A-Z] match code points within the written range. A caret immediately after the opening bracket negates the class: [^0-9] matches one character outside the ASCII digits.
Shorthand classes include \d for decimal digit, \s for whitespace, and \w for a word character under JavaScript’s rules. Uppercase versions negate them: \D, \S, and \W.
ASCII ranges do not represent every language. With Unicode-aware patterns, property escapes such as \p{Letter} can match letters across scripts when the u or appropriate Unicode mode is enabled and supported.
Quantifiers
Quantifiers repeat the preceding atom:
* zero or more
+ one or more
? zero or one
{3} exactly three
{2,5} between two and five
{4,} four or more
Quantifiers are greedy by default: they initially take as much as possible and give characters back if the rest of the pattern requires it. Adding ? makes a quantifier lazy, so .*? begins with as little as possible.
Greedy does not mean incorrect and lazy does not mean faster. The correct choice depends on the desired boundary and surrounding pattern.
Groups and alternatives
Parentheses group subexpressions and capture the matched text. (red|blue) car matches either phrase and records the colour in group 1.
Non-capturing groups use (?:...). They control precedence without creating a numbered result. Named capturing groups use (?<name>...), allowing code to refer to a stable name instead of a number.
The vertical bar has low precedence. cat|dog food means either cat or dog food, while (?:cat|dog) food requires the final word in both alternatives.
Anchors and boundaries
The caret ^ and dollar $ assert the start and end. Without the multiline flag they refer to the input boundaries, with details around final line terminators. With the m flag they can also match around line boundaries.
The word-boundary assertion \b matches a position between word and non-word characters. It consumes no text. JavaScript’s word-character definition is not a complete natural-language word tokenizer, so boundaries can surprise users working with non-Latin scripts or punctuation-heavy identifiers.
Use anchors when the entire field must conform. Testing whether any substring looks valid is different from validating the whole input.
Flags
The g flag enables global matching. Without it, JavaScript returns the first match. With it, the engine advances through the text and the tester lists successive matches.
The i flag enables case-insensitive matching. Unicode case folding has language-specific subtleties and is not identical to lowercasing both strings.
The m flag changes line anchors. The s flag makes dot match line terminators. The u flag enables Unicode-aware parsing and code-point behavior. The y sticky flag requires a match at the current search position. The d flag requests match indices in engines that support it, while the newer v mode adds Unicode set features where available.
Duplicate or incompatible flags produce a syntax error.
Match indexes and captures
Every match has a starting index measured in UTF-16 code units by JavaScript. Characters outside the Basic Multilingual Plane, including many emoji, occupy two code units. A displayed index may therefore differ from a human-perceived character count.
Capture groups show the text matched by each group. A group that did not participate is undefined, which differs from a group that participated and matched an empty string.
Global matching can return many results. The tester caps displayed matches at 200 to keep the page responsive and the result readable.
Catastrophic backtracking
Backtracking engines try alternatives when a later part of the pattern fails. Ambiguous nested repetitions can create an enormous number of possible paths.
A shape such as (a+)+$ applied to a long sequence of a characters followed by a non-matching character can repeatedly repartition the same input. Runtime may grow exponentially with input length.
This becomes a Regular Expression Denial of Service risk when an attacker controls the input and the application runs the expression on a shared server or UI thread. A pattern can be syntactically valid and still be operationally unsafe.
The tester runs expressions in a disposable Web Worker and terminates work after 300 milliseconds. That protects this page; it does not certify the pattern safe under longer inputs or another engine.
Reducing backtracking risk
Prefer specific character classes and bounded repetition. Avoid nested quantifiers over overlapping matches. Use unambiguous separators when the format provides them. Break complex validation into parsing steps instead of one expression.
Some regex engines support atomic groups or possessive quantifiers, but JavaScript support depends on the current specification and browser. Changing engines can change both syntax and performance.
Test adversarial near-matches, not only valid examples. A pattern often runs quickly on text that matches and slowly on a long string that fails at the final character.
Execution limits remain important even after review when patterns or input are untrusted.
Empty matches
Patterns such as a* can match an empty string. Under global matching, an engine must advance or it can repeat forever at the same position.
The tester explicitly moves forward after an empty global match. Production code should handle the same case when repeatedly calling exec or implementing its own match loop.
Empty matches can be legitimate for insertion points and assertions, but they often indicate that a validation expression is too permissive.
Validation versus parsing
Regex is useful for simple lexical formats: identifiers, fixed codes, delimiters, and extracting known shapes. It is less suitable as a complete parser for nested languages or large evolving specifications.
JSON, URLs, programming languages, and many date formats have dedicated parsers. Email addresses have a broader standard grammar than most application regexes attempt. HTML is hierarchical and error-tolerant, making a DOM parser more reliable.
A good workflow parses with the platform implementation, validates semantic requirements, and uses regex only for the local text patterns it handles clearly.
Replacement and escaping
Replacement strings form another small language. JavaScript replacement can refer to the full match, numbered groups, named groups, and surrounding text. Literal dollar signs may require escaping under those rules.
Building a regex from user-entered literal text also requires escaping regex metacharacters. Concatenating raw input into a pattern changes data into executable pattern syntax and can create incorrect matches or denial-of-service risk.
Use a well-tested escape function for literal fragments and keep trusted pattern structure separate from untrusted text.
Worked examples
The pattern \b[A-Z][a-z]+\b with global matching finds simple ASCII capitalized words. In “Ada wrote code with Grace,” it finds Ada and Grace. It does not define names across all languages or handle apostrophes and hyphens.
The pattern ^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})$ captures the numeric shape of an ISO-like date. It still accepts impossible values such as month 99. A date parser must perform calendar validation afterward.
The pattern \s+ finds runs of whitespace. Replacing each with one space can normalize simple text, but it also changes line breaks and tabs that may carry meaning.
Portability between engines
ECMAScript regex lacks or historically added features at different times from PCRE and other engines. Lookbehind, named groups, Unicode property escapes, set operations, inline modifiers, and atomic behavior vary.
A pattern passing in a current desktop browser may fail in an older runtime or a server using another language. Test in the actual deployment engine and document required versions.
Do not assume that identical syntax guarantees identical Unicode tables or performance. Engine updates can improve features and change optimization.
Limits of this tester
The tool uses the current browser’s JavaScript regex implementation. Patterns are limited to 500 characters, test text to 20,000 characters, displayed matches to 200, and execution to 300 milliseconds.
The timeout is a defensive boundary, not a formal complexity proof. It can reject a legitimate heavy test or allow a pattern that becomes dangerous on larger production input.
The tool does not perform replacements, generate code, compare dialects, or guarantee Unicode or browser compatibility. Use it to inspect matches and groups safely, then test and limit the expression in its real runtime.