Regex to JSON

Paste lines of text, write a regex with named capture groups, and get one JSON object per line — group names become keys. Coerce numbers and booleans, keep or drop unmatched lines, and output a JSON array or NDJSON. Runs in your browser; nothing is uploaded.

Try:
JSON records

About this tool

Regex to JSON turns unstructured lines — log files, command output, exports — into structured JSON. Write a regular expression with named capture groups and each line becomes one JSON object whose keys are the group names, in the order they appear in the pattern.

Worked example

Input lines:

10.0.0.5 GET /index.html 200 512
10.0.0.9 POST /api/login 401 87

Pattern (with Coerce types on):

(?<ip>\S+) (?<method>[A-Z]+) (?<path>\S+) (?<status>\d{3}) (?<bytes>\d+)

Output:

[
  { "ip": "10.0.0.5", "method": "GET", "path": "/index.html", "status": 200, "bytes": 512 },
  { "ip": "10.0.0.9", "method": "POST", "path": "/api/login", "status": 401, "bytes": 87 }
]

Limits and edge cases

Everything runs locally in your browser via WebAssembly — neither your text nor your pattern is uploaded.

FAQ

Why do I get "the pattern has no named capture groups"?

This tool builds JSON keys from group names, so at least one group must be named: write (?<status>\d{3}) instead of (\d{3}). Both the (?<name>…) and Python's (?P<name>…) spellings work. Plain numbered groups are ignored — if you only want a flat list of matches, the separate regex-extract tool does that.

What happens to lines that don't match the pattern?

By default they are skipped. Choose Keep as {"_raw": line} to carry them through the output unparsed (so you can spot format drift downstream), or Fail with an error to stop at the first non-matching line — the error names the 1-based line number and shows the line, which makes it a quick format validator. Blank lines never count as unmatched.

How does type coercion decide what becomes a number?

With Coerce types on, a capture becomes a JSON number only if it is a plain integer (42, -7) or plain decimal (3.14); exact true/false become booleans and exact null becomes null. Deliberately conservative: leading-zero values (007), scientific notation (1e5), thousands separators (1,000), and integers too big for 64 bits all stay strings, so identifiers survive untouched. Off by default — everything is a string.

Can one line produce more than one JSON object?

Yes — tick All matches per line. Instead of taking only the first match, every match on a line emits its own object. With the pattern (?<key>\w+)=(?<value>\S+) the line host=web1 region=eu yields two objects. The order is left-to-right within each line, top-to-bottom across lines.

Why doesn't my lookbehind or backreference work?

The engine is the Rust regex flavour, which guarantees linear-time matching — a hostile pattern can never hang the page. The trade-off is that look-around and backreferences are unsupported and rejected with a syntax error. In practice a named group around the part you want, plus anchors (^, $, which match per line here since each line is matched on its own), covers most patterns.

Developer & Automation Access

Run it from the terminal

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

gizza tool regex-to-json "10.0.0.5 GET /index.html 200 512
10.0.0.9 POST /api/login 401 87" 'pattern=(?<ip>\S+) (?<method>[A-Z]+) (?<path>\S+) (?<status>\d{3}) (?<bytes>\d+)'

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-to-json/?text=10.0.0.5%20GET%20%2Findex.html%20200%20512%0A10.0.0.9%20POST%20%2Fapi%2Flogin%20401%2087&pattern=%28%3F%3Cip%3E%5CS%2B%29%20%28%3F%3Cmethod%3E%5BA-Z%5D%2B%29%20%28%3F%3Cpath%3E%5CS%2B%29%20%28%3F%3Cstatus%3E%5Cd%7B3%7D%29%20%28%3F%3Cbytes%3E%5Cd%2B%29&ignore_case=true&all_matches=true&unmatched=skip&coerce_types=true&output=json

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