Open-Source Wikis

/

ripgrep

/

Features

/

PCRE2 support

BurntSushi/ripgrep

PCRE2 support

ripgrep's default regex engine is Rust's regex crate, which uses finite automata for guaranteed linear-time matching. PCRE2 is a different engine with a different feature set — most notably, look-around and backreferences. ripgrep can be built with optional PCRE2 support to expose those features.

When to use PCRE2

-P/--pcre2 switches to PCRE2 for the current invocation. Use it when you need:

  • Look-ahead: foo(?=bar)
  • Look-behind: (?<=foo)bar
  • Negative variants: (?!...), (?<!...)
  • Backreferences: (\w+)\s+\1

…and accept the trade-off:

  • PCRE2 has worst-case exponential time on pathological patterns. Rust's regex is always linear.
  • PCRE2 startup is slower; the JIT (when enabled) recovers most of that cost on long searches.
  • PCRE2 binary size adds ~1 MiB to the rg executable.

Engine selection

There are several flags that all affect engine choice:

  • --engine default — Rust regex (the default).
  • --engine pcre2 — equivalent to -P.
  • --engine auto (alias --auto-hybrid-regex) — try Rust regex first; if compilation fails because of an unsupported feature, retry with PCRE2.

The selection logic lives in crates/core/flags/hiargs.rs (the matcher() method). It examines the engine field on LowArgs and decides whether to construct a grep_regex::RegexMatcher or a grep_pcre2::RegexMatcher.

--pcre2-version prints the linked PCRE2 version and JIT availability, and exits with code 1 if PCRE2 isn't compiled in. Implemented in crates/core/flags/doc/version.rs::generate_pcre2.

Building with PCRE2

The pcre2 Cargo feature gates everything PCRE2-related:

cargo build --release --features pcre2

The build:

  1. The pcre2-sys crate's build.rs looks for a system PCRE2 library via pkg-config.
  2. If found, links dynamically against it.
  3. If not, builds PCRE2 from the source bundled in the crate using the system C compiler and links statically.

PCRE2_SYS_STATIC=1 forces the static path. The musl Linux release binaries always build statically because musl deliberately avoids pkg-config system libraries.

The [features] chain:

ripgrep::pcre2  →  grep::pcre2  →  grep-pcre2

When the feature is off, crates/pcre2 isn't compiled and the grep::pcre2 re-export is hidden behind #[cfg(feature = "pcre2")]. ripgrep gracefully prints "PCRE2 is not available in this build" if -P is passed.

Implementation handoff

graph LR
    CLI["-P or --engine"] --> Hiargs["HiArgs::matcher()"]
    Hiargs -->|engine = pcre2| Pcre2Matcher["grep_pcre2::RegexMatcher"]
    Hiargs -->|engine = default| RustMatcher["grep_regex::RegexMatcher"]
    Pcre2Matcher --> Trait["impl grep_matcher::Matcher"]
    RustMatcher --> Trait
    Trait --> Searcher

Both matchers implement the same Matcher trait, so the rest of the pipeline (searcher, sinks, printers) doesn't know or care which engine is in play.

Important platform note

A 15.0.0 fix (BUG #3155) statically compiles PCRE2 into the macOS aarch64 release binary. Earlier releases tried dynamic linking, which broke on systems where Homebrew PCRE2 wasn't installed.

Reference: file & function pointers

What Where
grep_pcre2::RegexMatcher crates/pcre2/src/matcher.rs
--pcre2, --engine, --auto-hybrid-regex flags crates/core/flags/defs.rs
Engine selection logic crates/core/flags/hiargs.rs::matcher
--pcre2-version printer crates/core/flags/doc/version.rs
Build-time gating crates/pcre2/Cargo.toml, Cargo.toml ([features] section)
Static-vs-dynamic link decision pcre2-sys crate's build script (external)

For the package-level overview see packages: pcre2.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

PCRE2 support – ripgrep wiki | Factory