FileKiln

Regex Tester

Test JavaScript regular expressions against sample text: every match, index, and capture group listed. Nothing you test is uploaded.

Ready when you areregex test
Runs on your computer. Nothing gets uploaded.

Your stuff stays yours. The conversion happens in this page's JavaScript. Nothing you paste here leaves your machine, and the tool keeps working with the network unplugged.

The first line of the input is your pattern - either /pattern/flags or a bare pattern - and everything below it is the text to search. The output lists every match with its character index, plus every capture group, numbered and named. This is the actual JavaScript regex engine, not an approximation, so what matches here matches in Node and the browser: lookaheads, named groups (?<name>…), and Unicode escapes with the u flag all behave exactly as they will in your code. Regex testers are where people paste production log lines and API responses; this one keeps them on your machine.

How to test a regular expression

  1. On the first line of Pattern + text in, type your pattern. Use /pattern/flags when you want flags, or type the bare pattern with no slashes.
  2. Press Enter and paste the text you want to search on the lines below. Everything after the first line break is the search text, including any further line breaks.
  3. Press Test.
  4. Read Matches out. The first line gives the match count and the flags actually used. Each match follows, numbered, with its start position after @, the matched text in quotes, and any capture groups indented underneath.
  5. Adjust the pattern on line 1 and press Test again. Copy result copies the report, and Clear empties both boxes.

JavaScript regex syntax and flags in practice

A regular expression is a small program that describes text. The pieces you will use most:

  • Character classes: \d is a digit, \w is a letter, digit, or underscore (ASCII only, so it does not match é), \s is whitespace, and [a-f0-9] is any one character from the set. . matches any character except a line break.
  • Quantifiers: * is zero or more, + is one or more, ? is zero or one, {2,4} is two to four. Adding ? after a quantifier (.*?) makes it match as little as possible.
  • Anchors: ^ and $ match the start and end of the whole text, or of each line with the m flag. \b matches a word boundary.
  • Groups: ( ) captures, (?: ) groups without capturing, and (?<name> ) captures with a name.

The flags JavaScript accepts are d (match indices), g (global), i (ignore case), m (multiline anchors), s (dot also matches line breaks), u (Unicode mode, needed for \p{...} property escapes), v (an upgraded Unicode mode in newer browsers), and y (sticky). This tester always adds g if you leave it out, which is why the summary line might say flags: mg when you typed only m. The full grammar lives in the ECMAScript specification.

Each group is listed twice when it is named: once by number and once by name. Groups that took part in the pattern but matched nothing, such as an optional group that was skipped, show (no match). Matched text is shown as a JSON string, so a line break inside a match appears as \n and a quote appears as \".

A worked example

Input, pattern on line 1 and the text below it:

/(?<year>\d{4})-(?<month>\d{2})/
2026-09 and 1999-12

Output:

2 matches   (flags: g)

1. @0  "2026-09"
     group 1: "2026"
     group 2: "09"
     <year>: "2026"
     <month>: "09"
2. @12  "1999-12"
     group 1: "1999"
     group 2: "12"
     <year>: "1999"
     <month>: "12"

The positions count from the first character of the search text, which is line 2 of the input box. The pattern line and its line break are not part of the count, so @0 is the 2 at the start of 2026-09.

Common problems and how to fix them

A pattern with leading or trailing spaces behaves differently

Line 1 is trimmed before it is used. A bare pattern of a space followed by +, meant to match runs of spaces, becomes just + and fails with Invalid regex: ... Nothing to repeat. Write spaces you care about as \s, [ ], or \x20, or put the pattern inside slashes with the space not at an edge.

A bare pattern containing slashes gives "Invalid flags"

If line 1 starts with /, the tester looks for a closing / followed by letters and treats those letters as flags. The bare pattern /usr/local is read as pattern usr with flags local, which is an error. Escape the slashes and wrap the pattern: /\/usr\/local/ matches /usr/local correctly.

^ and $ never match when the text has several lines

Without the m flag, ^\d+$ means "the whole text is digits", and a multi-line sample never qualifies. Add m: /^\d+$/m tests each line on its own.

The sticky flag returns no matches

With y, every match must begin exactly where the previous one ended, starting at position 0. Against foo boo, the pattern /o/y fails immediately because position 0 is f. Remove y unless you are writing a tokenizer that needs it.

The count stops at exactly 1000

The tester lists at most 1000 matches and does not say when it stops early, so a result of 1000 matches may mean more exist. Test against a smaller sample, or make the pattern more specific.

Related tasks

If you are pulling unique values out of a log, copy the matched lines into remove duplicate lines afterward. For comparing two outputs, the text diff checker shows exactly which lines changed.

Questions this tool gets asked

Which regex flavor is this?

JavaScript's, exactly - the tool runs your pattern through the browser's own engine. Perl/PCRE features that JavaScript lacks (possessive quantifiers, recursion) won't work here, and won't work in your JavaScript code either, which is the useful truth.

What flags can I use?

Any JavaScript flags: i (ignore case), m (multiline ^ and $), s (dot matches newline), u (Unicode), and g. The g flag is always applied so every match is listed, not just the first.

What does “@12” mean in the output?

The character index where that match starts, counting from 0 at the beginning of the text (line breaks count as one character). Indexes are what String.match and exec return, so they line up with your code.

Why does my pattern match empty strings repeatedly?

Patterns where everything is optional (like a*) match the empty string at every position. The tester steps past empty matches to avoid looping forever, but the fix is a pattern that requires at least one character, like a+.

Related tools