re
a recursive grep with boolean constraints - find lines (or paragraphs, or files) matching all of your terms at once. powered by RE#.
basic usage
adding constraints
-a / --add requires each term to appear within the match scope (default: line).
| flag | effect |
|---|---|
-a / --add |
must contain pattern |
-F / --lit |
must contain literal string (no regex) |
-N / --not |
must not contain pattern |
controlling scope
by default, all constraints must be satisfied within a single line. --scope changes this boundary:
| scope | how to use | constraints must match within |
|---|---|---|
| line | (default) | a single line |
| paragraph | -p or --scope paragraph |
text blocks separated by blank lines |
| file | --scope file |
anywhere in the same file |
| custom | --scope '<pattern>' |
match must not cross the pattern |
-p word is shorthand for --scope paragraph --add word.
proximity search
--near N constrains all terms to appear within N lines of each other:
the RE# pattern language
beyond flag-based constraints, you can write patterns directly using operators that standard regex doesn't have:
| operator | meaning | example |
|---|---|---|
& |
intersection - both sides must match | (foo)&(bar) |
~ |
complement - exclude what follows | ~(_*debug_*) |
_ |
wildcard - like . but also matches newlines |
_*error_* |
_ is what makes multi-line and paragraph searches work. use \_ for a literal underscore, -R for standard regex mode, or -F for fixed strings.
try patterns interactively in the web playground.
differences from ripgrep
most ripgrep flags work the same. the differences:
| ripgrep | re | reason |
|---|---|---|
-a / --text |
-uuu |
-a is --and/--add in re |
_ is literal |
_ is wildcard |
use -R or \_ for literal |
| standard regex only | &, ~, _ operators |
use -R for standard regex mode |
exit codes
0 match found, 1 no match, 2 error
install
cargo
prebuilt binaries
download from GitHub releases.
nix
or in a flake:
inputs.resharp.url = "github:ieviev/resharp-grep";
nix package includes shell completions.
how it works
all flags compile down to RE# patterns. for example:
compiles to:
(_*unsafe_*) & (_*unwrap_*) & ~((_*\n_*){6})
--add terms become intersections (_*word_*), --near 5 rejects spans with 6+ newlines via complement (~), and scopes add their own boundary constraint. because everything shares the same representation, all output modes (highlighting, context, --count, --json, etc.) work uniformly.
see the RE# engine for more on the regex algebra.
Have fun!