Regex Tester
Test regular expressions against real sample text with a match list, capture group extraction, and replacement preview, all running via WebAssembly.
What it does
- Lists every match with start and end offsets
- Capture group extraction per match
- Find-and-replace preview with $1 and ${name} references
- Flags g, i, m, s selectable independently
- Linear-time engine: no catastrophic backtracking
Enter a pattern, paste the text to search, choose your flags and click Test: the tool lists every match with its position and the content of each capture group. Add a replacement string and click Replace to preview the text after a find-and-replace, then copy it. Patterns are compiled by the Rust regex crate, the engine used by tools such as ripgrep, running in WebAssembly in your browser. Log extracts, customer data or source code you test against are never uploaded.
How to test a regular expression
- Type the pattern in Pattern, without surrounding slashes:
(\d{4})-(\d{2}), not/(\d{4})-(\d{2})/g. - Toggle the flags you need (
gis on by default). - Paste your sample text into Input Text.
- Click Test. The counter shows the number of matches, and each match card shows its text, its
startandendoffsets, and each capture group with its own offsets. - Optionally type a Replacement such as
$2/$1and click Replace. The output box shows the transformed text and the status line gives the number of replacements.
Flags explained
- g (global): find all matches. Without it, only the first match is reported and only the first occurrence is replaced.
- i (case-insensitive):
erroralso matchesERRORandError, including for accented and non-Latin letters. - m (multi-line):
^and$match at the start and end of every line instead of only the whole text. Needed to anchor patterns on log lines. - s (dot-all):
.also matches line breaks, for patterns that span several lines. - u (Unicode): Unicode support is always on in this engine, so
\wand\dalready match letters and digits from all scripts. The button is accepted for compatibility with JavaScript habits and changes nothing.
Inline flags work too: (?i) at the start of the pattern makes it case-insensitive without the button.
Syntax supported, and what differs from JavaScript or PCRE
The Rust engine supports the syntax you use most: character classes ([a-z], \d, \w, \s), quantifiers (*, +, ?, {2,5} and their lazy versions), alternation, anchors, word boundaries \b, non-capturing groups (?:...), named groups (?<year>...) or (?P<year>...), and Unicode classes such as \p{L}.
Two features are deliberately absent, and a pattern using them is rejected with an explicit error:
- Lookaround: lookahead
(?=...), negative lookahead(?!...)and lookbehind(?<=...). - Backreferences like
\1inside the pattern.
This is the price of a strong guarantee: matching time grows linearly with the input, so no pattern can freeze the page with catastrophic backtracking, which is the cause of many regex denial-of-service bugs in backtracking engines. If your target is JavaScript, Python or PCRE and you rely on lookarounds, test those parts in an environment with that engine.
Replacement syntax
$1,$2: content of numbered groups.$0is the whole match.${year}: content of a named group.${1}abc: use braces when a group number is followed by letters or digits, otherwise$1abcis read as a group named "1abc" and inserts nothing.$$: a literal dollar sign.
Reading positions
The start and end values are byte offsets in the UTF-8 text, with end excluded. For plain ASCII they equal character positions. Accented letters take two bytes and emoji four, so on text like "café" the offsets after the é are one higher than a character count. Groups that did not take part in a match are listed as having no match.
Typical uses
- Writing a pattern to extract IDs, emails or dates from logs, then checking every capture before putting it in code.
- Preparing a find-and-replace for a CSV or a config file, with a preview of the result before running it on the real file.
- Building patterns for tools that use the same engine or a similar syntax, such as ripgrep, or Rust programs.
Privacy: your sample text stays local
To test a pattern properly you need real data: production logs with IP addresses and user IDs, customer exports, source files. Online regex testers that evaluate on a server, or that save sessions to share them, keep copies of that text. Here the pattern is compiled and executed in WebAssembly in your tab, and nothing is transmitted or saved.
Frequently asked questions
- Is the text I test against uploaded?
- No. Matching and replacement run in your browser. Neither the pattern nor the text is sent anywhere.
- Why is my lookahead rejected?
- The Rust regex engine does not support lookaround or backreferences, in exchange for guaranteed linear-time matching. Rewrite the pattern with capture groups, or test it in an engine that supports those features.
- Does the tester update as I type?
- No. Click Test or Replace to run the pattern. This keeps the page responsive on large inputs.
- Why do offsets not match the character count?
- Offsets are counted in UTF-8 bytes. Non-ASCII characters take two to four bytes, which shifts positions after them.
- Will my pattern work in JavaScript or Python?
- Most everyday syntax is shared. Differences appear with lookarounds and backreferences (not supported here), and with some named-group and escape details. Check the documentation of your target engine for those parts.
- What does the u flag do?
- Nothing extra: Unicode matching is always enabled in this engine.
Related tools: compare a text before and after a replacement with the text diff tool, or escape special characters in URLs with the URL encoder and decoder.