Bulk Regex Matcher

Paste many lines, enter one regular expression, and get a per-line report: matched or not matched, the matched text, capture groups, and optional offsets. Filter to only matching or non-matching rows and export as text, JSON, or CSV. Nothing is uploaded.

Try:
Match report

About this tool

A regular expression tester is useful for one sample. Real cleanup and validation jobs usually start with a list: hundreds of IDs, email addresses, log lines, filenames, or pasted rows from a spreadsheet. This tool applies one regex to every line and reports the verdict for each line, so you can see both the matches and the failures without losing line numbers.

The report includes totals, the matched substring, capture groups, and optional byte offsets. Named capture groups such as (?<year>\d{4}) keep their names in text, JSON, and CSV output. Everything runs locally in your browser; the pasted data is not uploaded.

Worked example

Lines:

[email protected]
not-an-email
[email protected]

Pattern:

^[\w.+-]+@([\w-]+\.[\w.]+)$

With require whole-line match and capture groups on, the text report shows two matches and one failure:

Lines tested: 3
Matched: 2
Not matched: 1

line 1: MATCH    "[email protected]" | 1=example.com
line 2: NO MATCH "not-an-email"
line 3: MATCH    "[email protected]" | 1=test.org

Switch to CSV when you want one row per input line and one column per capture group, or JSON when another script will consume the result.

What you can control

Limits and edge cases

FAQ

How is this different from a normal regex tester?

A normal tester highlights matches in one text blob. This tool treats each line as a separate case and gives every line a pass/fail verdict. That makes it better for validating pasted lists: you can filter to only failures, keep original line numbers, and export the result as CSV or JSON.

Can I use named capture groups?

Yes. Rust regex named groups use the (?<name>...) syntax. Named groups appear by name in the text report and as named columns in CSV output; unnamed groups use group_1, group_2, and so on.

Why does my PCRE pattern fail?

Rust regex deliberately omits backreferences and look-around so matching stays predictable and linear-time. Patterns with (?=...), (?<=...), or \1 return an invalid-pattern error. Rewrite the pattern without those features, or use a PCRE-specific tester when that syntax is required.

What does whole-line match do?

It makes the entire tested line satisfy the pattern. Without it, \d+ matches abc123 because the digits occur somewhere inside the line. With whole-line match on, abc123 fails unless your pattern accounts for the letters too.

Why are positions called byte offsets?

The Rust regex engine reports byte offsets. For English letters and digits, byte offsets are the same as character positions. For multi-byte Unicode characters, a visual character may occupy more than one byte, so offsets can look larger than the number of visible characters before the match.

Developer & Automation Access

Run it from the terminal

Same engine as this page, headless — via the gizza CLI:

gizza tool regex-bulk-match "[email protected]
not-an-email
[email protected]" 'pattern=^[\w.+-]+@([\w-]+\.[\w.]+)$'

New to the CLI? Get gizza →

Open it by URL

Pre-fill and auto-run this tool with query parameters — the names match the API/CLI:

https://gizza.ai/tools/regex-bulk-match/?lines=ada%40example.com%0Anot-an-email%0Abo%40test.org&pattern=%5E%5B%5Cw.%2B-%5D%2B%40%28%5B%5Cw-%5D%2B%5C.%5B%5Cw.%5D%2B%29%24&show=all&output=text&max_lines=1000&full_match=true&ignore_case=true&dotall=true&trim=true&skip_blank=true&captures=true&show_position=true

Machine-readable descriptor: tool.json — title + parameters JSON Schema for agents.