rgx-cli 0.12.0

A terminal regex tester with real-time matching, multi-engine support, and plain-English explanations
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
<div align="center">

# rgx

**A terminal regex tester with real-time matching and multi-engine support**

[![CI](https://github.com/brevity1swos/rgx/actions/workflows/ci.yml/badge.svg)](https://github.com/brevity1swos/rgx/actions/workflows/ci.yml)
[![Crates.io](https://img.shields.io/crates/v/rgx-cli.svg)](https://crates.io/crates/rgx-cli)
[![Downloads](https://img.shields.io/crates/d/rgx-cli.svg)](https://crates.io/crates/rgx-cli)
[![License](https://img.shields.io/crates/l/rgx.svg)](LICENSE-MIT)

Test and debug regular expressions without leaving your terminal. Written in Rust.

![demo](https://raw.githubusercontent.com/brevity1swos/rgx/main/assets/demo.gif?v=6)

*Press F1 in the app for a multi-page cheat sheet with keyboard shortcuts, regex syntax, and engine-specific features.*

</div>

---

## Who is this for?

rgx is useful if you:

- **Work on remote servers** where opening a browser isn't practical — SSH sessions, containers, air-gapped environments
- **Want to pipe regex results** into other commands (`echo "log" | rgx -p '\d+' | sort`) — regex101 can't do this
- **Need to test against specific engine behavior** — check if your pattern works in Rust's `regex` crate vs PCRE2 without guessing
- **Prefer staying in the terminal** and find the context switch to a browser tab disruptive

If you write regex a few times a month and regex101.com works fine for you, it probably still will. rgx is strongest for developers who do regex-heavy work in terminal-centric workflows.

## Features

- **Real-time matching** — matches update on every keystroke
- **Syntax-highlighted pattern input** — AST-based coloring for groups, quantifiers, character classes, anchors, and escapes
- **3 regex engines** — Rust `regex` (default), `fancy-regex` (lookaround/backrefs), PCRE2 (full features)
- **Capture group highlighting** — distinct colors per group, nested group support
- **Plain-English explanations** — walks the regex AST to generate human-readable breakdowns
- **Replace/substitution mode** — live preview with `$1`, `${name}`, `$0`/`$&` syntax
- **Match detail + clipboard** — navigate matches/captures with Up/Down, copy with Ctrl+Y
- **Pattern history + undo** — Ctrl+Z/Ctrl+Shift+Z undo/redo, Alt+Up/Down browse history
- **Context-sensitive cheat sheet** — F1 multi-page help: shortcuts, regex syntax, engine-specific features
- **Whitespace visualization** — toggle with Ctrl+W to show spaces as `·`, newlines as ``, tabs as ``
- **Mouse support** — click to focus/position cursor, scroll to navigate panels
- **Engine selector** — switch engines with Ctrl+E, see where behavior differs
- **Regex flags** — toggle case-insensitive, multiline, dotall, unicode, extended
- **Stdin pipe support**`echo "test string" | rgx '\d+'`
- **Non-interactive batch mode**`rgx -p -t "input" 'pattern'` prints matches to stdout and exits
- **JSON output**`--json` outputs structured match data with positions and capture groups
- **Colored output**`--color auto|always|never` highlights matches like `grep --color`
- **Pipeline composability** — pipe in, filter, pipe out: `cat log | rgx -p '\d+' | sort -n`
- **regex101 URL export** — Ctrl+U generates a regex101.com URL and copies to clipboard
- **Project workspaces**`-w project.toml` saves/loads regex state to a file — track in git
- **Shell completions**`--completions bash|zsh|fish` for tab completion
- **Vim mode** — optional modal editing (`--vim` or `vim_mode = true`) with Normal/Insert modes, h/j/k/l navigation, w/b/e word motions, dd/cc/x editing, and all global shortcuts preserved
- **Recipe library** — built-in common patterns (email, URL, IP, semver, etc.) — Ctrl+R to browse and load
- **Code generation** — Ctrl+G generates ready-to-use code in Rust, Python, JavaScript, Go, Java, C#, PHP, or Ruby — copies to clipboard
- **Generate regex from examples** — Ctrl+X opens an overlay where you enter example strings (one per line) and get back a regex via the [grex]https://crates.io/crates/grex crate; Tab to load it into the main editor
- **Live filter mode**`rgx filter [PATTERN]` reads stdin or a file, shows an interactive TUI where you refine a regex against the stream, and emits matching lines on Enter. Supports `--invert`, `--count`, `--line-number`, `--case-insensitive`, `--json <PATH>` (match against a JSONL field rather than the raw line), and piping (non-TTY stdout skips the TUI entirely).
- **Auto engine selection** — automatically upgrades to fancy-regex or PCRE2 when your pattern uses lookahead, backreferences, or recursion
- **Test suite mode**`rgx --test file.toml` validates regex against should-match/should-not-match assertions — CI-friendly exit codes
- **Alternating match colors** — adjacent matches use distinct background colors for visual clarity
- **Step-through debugger** — Ctrl+D opens a full-screen debugger that traces PCRE2 execution step by step, highlights the current pattern token and input position, shows backtracking, and includes a heatmap mode to reveal catastrophic backtracking at a glance
- **Cross-platform** — Linux, macOS, Windows

## Installation

### From crates.io

```bash
cargo install rgx-cli
```

### From prebuilt binaries

Download from [GitHub Releases](https://github.com/brevity1swos/rgx/releases/latest).

### Shell installer

```bash
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/brevity1swos/rgx/releases/latest/download/rgx-installer.sh | sh
```

### Homebrew

```bash
brew install brevity1swos/tap/rgx
```

### Arch Linux (AUR)

```bash
yay -S rgx-cli        # or rgx-cli-bin for prebuilt
```

<details>
<summary>More installation methods</summary>

### From source

```bash
git clone https://github.com/brevity1swos/rgx.git
cd rgx
cargo install --path .
```

### With PCRE2 engine (requires libpcre2-dev)

```bash
cargo install rgx-cli --features pcre2-engine
```

> **Security note:** PCRE2 **10.45** is affected by [CVE-2025-58050]https://nvd.nist.gov/vuln/detail/CVE-2025-58050 — a heap-buffer-overflow reachable via patterns that use scan-substring `(*scs:)` verbs combined with backreferences. If you build rgx with `pcre2-engine` and link it against PCRE2 10.45, rgx will display a warning in the status bar. Upgrade your system's PCRE2 package to **>= 10.46** to resolve.

</details>

## Usage

```bash
# Interactive mode
rgx

# Vim mode (modal editing)
rgx --vim

# Start with a pattern
rgx '\d{3}-\d{3}-\d{4}'

# Pipe text from stdin
echo "Call 555-123-4567 or 555-987-6543" | rgx '\d{3}-\d{3}-\d{4}'

# Use a specific engine
rgx --engine fancy '\w+(?=@)'

# With flags
rgx -i 'hello'

# With replacement template
rgx -r '$2/$1' '(\w+)@(\w+)'

# Non-interactive batch mode (--print / -p)
rgx -p -t "hello 42 world 99" '\d+'    # prints: 42\n99
echo "log line 404" | rgx -p '\d+'     # prints: 404

# Count matches only (--count / -c)
echo "a1 b2 c3" | rgx -p -c '\d+'     # prints: 3

# Extract a specific capture group (--group / -g)
echo "user@host" | rgx -p -g 1 '(\w+)@(\w+)'  # prints: user

# Batch replacement
rgx -p -t "user@host" -r '$2=$1' '(\w+)@(\w+)'   # prints: host=user

# JSON output with match positions and capture groups
echo "error at line 42" | rgx -p '(\d+)' --json

# Colored output (like grep --color)
cat server.log | rgx -p 'ERROR: (.*)' --color always

# Pipeline composability
cat server.log | rgx -p 'ERROR: (.*)' | sort | uniq -c

# Project workspace — save/load regex state to a file
rgx -w ~/project/regex/parse_urls.toml

# Capture final pattern after interactive editing
PATTERN=$(rgx -P)

# Test suite mode — validate regex assertions in CI
rgx --test tests/url_patterns.toml tests/email_patterns.toml

# Generate shell completions
rgx --completions bash > ~/.local/share/bash-completion/completions/rgx

# Exit codes: 0 = match found, 1 = no match, 2 = error
rgx -p -t "test" '\d+' || echo "no digits found"
```

## Keyboard Shortcuts

| Key | Action |
|-----|--------|
| `Tab` | Cycle focus: pattern / test / replace / matches / explanation |
| `Up/Down` | Scroll panel / move cursor / select match |
| `Enter` | Insert newline (test string) |
| `Ctrl+E` | Cycle regex engine |
| `Ctrl+Z` | Undo |
| `Ctrl+Shift+Z` | Redo |
| `Ctrl+Y` | Copy selected match to clipboard |
| `Ctrl+R` | Open regex recipe library |
| `Ctrl+W` | Toggle whitespace visualization |
| `Ctrl+O` | Output results to stdout and quit |
| `Ctrl+S` | Save workspace |
| `Ctrl+G` | Generate code in 8 languages (copies to clipboard) |
| `Ctrl+X` | Generate regex from examples (grex) |
| `Ctrl+U` | Copy regex101.com URL to clipboard |
| `Ctrl+D` | Step-through regex debugger (PCRE2) |
| `Ctrl+B` | Benchmark pattern across all engines |
| `Ctrl+Left/Right` | Move cursor by word |
| `Alt+Up/Down` | Browse pattern history |
| `Alt+i/m/s/u/x` | Toggle flags (case, multiline, dotall, unicode, extended) |
| `F1` | Show help (Left/Right to page through) |
| `Mouse click` | Focus panel and position cursor |
| `Mouse scroll` | Scroll panel under cursor |
| `Esc` | Quit (or Normal mode in vim) |

### Vim Mode (`--vim`)

| Key | Mode | Action |
|-----|------|--------|
| `i` / `a` / `I` / `A` | Normal | Enter Insert mode (at cursor / after / line start / line end) |
| `o` / `O` | Normal | Open line below / above and enter Insert mode |
| `Esc` | Insert | Return to Normal mode |
| `h` / `j` / `k` / `l` | Normal | Left / down / up / right |
| `w` / `b` / `e` | Normal | Word forward / backward / end |
| `0` / `$` / `^` | Normal | Line start / end / first non-blank |
| `gg` / `G` | Normal | First line / last line |
| `x` | Normal | Delete character under cursor |
| `dd` | Normal | Delete line |
| `cc` | Normal | Clear line and enter Insert mode |
| `u` | Normal | Undo |
| `p` | Normal | Paste from clipboard |
| `Esc` | Normal | Quit |

All global shortcuts (`Ctrl+*`, `Alt+*`, `F1`, `Tab`) work in both modes.

### Filter mode (`rgx filter`) shortcuts

| Key | Action |
|-----|--------|
| `Up/Down` | Browse matching lines |
| `Alt+i` | Toggle case-insensitive |
| `Alt+v` | Toggle invert match |
| `Enter` | Emit matched lines to stdout and exit (exit 0) |
| `Esc` / `q` / `Ctrl+C` | Discard and exit (exit 1) |
| Typing / Backspace | Edit the regex pattern (re-filters live) |

## Piping recipes

`rgx filter` detects whether stdout is a terminal. If it's piped, the TUI is
skipped — it behaves like a regular `grep`-style filter.

### General

```bash
# Count error lines in a log
cat /var/log/system.log | rgx filter --count 'error|fail'

# Emit only non-matching lines (like grep -v)
cat access.log | rgx filter -v '200 '

# Prefix matches with line numbers
rgx filter -f server.log -n 'Exception'
```

### JSONL field extraction (`--json`)

When your input is JSONL (one JSON object per line), the default behavior
matches the pattern against the full raw line — which often means you hit
timestamps, IDs, or other structured metadata by accident. Use `--json <PATH>`
to filter on a specific field instead:

```bash
# Match only the `msg` field of each JSONL record, not the raw line
cat app.jsonl | rgx filter --json '.msg' '(?i)error'

# Count records whose nested text field starts with "boom"
cat events.jsonl | rgx filter --json '.payload.text' --count '^boom'
```

The path language is minimal on purpose: `.field` for object keys, `[N]`
for array indices, nesting as `.a.b[0].c`. Each line is parsed as JSON,
the extracted field's string value is what the pattern matches against,
and non-string values / missing paths / malformed JSON lines are skipped
silently. Raw JSON lines are still what gets emitted when a match hits —
so downstream tools receive the full record, not just the extracted field.

### Filtering diffs

```bash
# See every diff line that adds a console.log call
git diff | rgx filter '^\+.*console\.log'

# Count TODO markers added in the working tree
git diff HEAD | rgx filter --count '^\+.*TODO'
```

Once a pattern matches what you want interactively, you can copy-paste it
into any policy or CI check.

## Engines

| Engine | Features | Dependencies |
|--------|----------|-------------|
| **Rust regex** (default) | Fast, linear time, Unicode | Pure Rust |
| **fancy-regex** | + lookaround, backreferences | Pure Rust |
| **PCRE2** | + possessive quantifiers, recursion, conditionals | Requires libpcre2 |

## Comparison

### vs. terminal alternatives

| Feature | rgx | regex-tui | rexi |
|---------|:---:|:---------:|:----:|
| Real-time matching | Yes | Yes | Yes |
| Multiple engines | 3 | 2 | 1 |
| Capture group highlighting | Yes | No | No |
| Plain-English explanations | Yes | No | No |
| Replace/substitution | Yes | No | No |
| Match clipboard copy | Yes | No | No |
| Undo/redo | Yes | No | No |
| Whitespace visualization | Yes | Yes | No |
| Mouse support | Yes | No | No |
| Regex flags toggle | Yes | Yes | No |
| Stdin pipe support | Yes | Yes | Yes |
| Built-in recipe library | Yes | No | No |
| Vim keybindings | Yes | No | No |
| Non-interactive batch mode | Yes | No | No |
| JSON output | Yes | No | No |
| Colored batch output | Yes | No | No |
| regex101 URL export | Yes | No | No |
| Code generation | Yes (8 langs) | No | No |
| Auto engine selection | Yes | No | No |
| Test suite mode | Yes | No | No |
| Step-through debugger | Yes (PCRE2) | No | No |
| Shell completions | Yes | No | No |

### vs. regex101.com

regex101.com has 8 engines, shareable permalinks, and a community pattern library. rgx doesn't try to replace it — but it now has its own step-through debugger with backtracking visualization and heatmap mode. Where rgx is useful instead:

- **Offline/remote work** — no browser or internet needed
- **Pipeline integration**`echo data | rgx -p 'pattern' | next-command` — non-interactive batch mode with proper exit codes
- **Code generation** — Ctrl+G generates code for Rust, Python, JavaScript, Go, Java, C#, PHP, Ruby
- **Engine-specific testing** — test against Rust's `regex` crate directly (regex101 doesn't have this engine)
- **Test suite mode**`rgx --test file.toml` for CI-integrated regex validation
- **Workspace save/restore** — save your session and pick up later (`-w project.toml`)
- **Step-through debugger** — Ctrl+D traces PCRE2 execution with backtracking visualization and heatmap — no browser needed
- **Bridge to regex101** — Ctrl+U exports your current state as a regex101.com URL for sharing

## Test Suite Mode

Validate regex patterns against assertions in CI pipelines:

```toml
# tests/urls.toml
pattern = "https?://[^\\s]+"
engine = "rust"

[[tests]]
input = "visit https://example.com today"
should_match = true

[[tests]]
input = "no url here"
should_match = false
```

```bash
rgx --test tests/urls.toml tests/emails.toml
# Exit code: 0 = all pass, 1 = failures, 2 = error
```

## Configuration

rgx looks for a config file at `~/.config/rgx/config.toml`:

```toml
default_engine = "rust"  # "rust", "fancy", or "pcre2"
vim_mode = false          # enable vim-style modal editing
```

## Editor & Terminal Integration

### VS Code

Install from the [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=brevity1swos.rgx), or search "rgx" in the Extensions panel.

**Commands** (open via `Ctrl+Shift+P` / `Cmd+Shift+P`):
- `rgx: Open` — launch rgx in the integrated terminal
- `rgx: Open with Selection` — pass selected text as test input
- `rgx: Open with Pattern` — pass selected text as the regex pattern

### Neovim

Using [lazy.nvim](https://github.com/folke/lazy.nvim):

```lua
{ dir = "path/to/rgx/plugin/nvim" }
```

Or copy `plugin/nvim/lua/rgx/init.lua` to your Neovim config:

```lua
require("rgx").setup()
```

**Commands:**
- `:Rgx` — open rgx in a floating terminal
- `:Rgx pattern` — open with a pre-filled pattern
- Visual select + `:'<,'>Rgx` — pass selection as test input

### Zed

Copy `plugin/zed/tasks.json` to your project's `.zed/tasks.json` (or merge into an existing one).

Run tasks via `Cmd+Shift+P` → "task: spawn" → select an rgx task.

### tmux

```bash
# Open rgx in a tmux popup
tmux display-popup -E -w 80% -h 80% rgx

# Open with a pattern
tmux display-popup -E -w 80% -h 80% -- rgx '\d+'
```

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for details.

## License

Licensed under either of

- Apache License, Version 2.0 ([LICENSE-APACHE]LICENSE-APACHE)
- MIT License ([LICENSE-MIT]LICENSE-MIT)

at your option.