rg — Regex Patterns
Regex Engine
rg '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}' /etc/hosts
rg uses the Rust regex crate by default. Supports: character classes, quantifiers, alternation, grouping, non-greedy. Does NOT support: backreferences (\1), lookaheads, lookbehinds. This is a deliberate tradeoff — the Rust engine guarantees linear-time matching.
rg -P '(?<=host:\s)\S+' /etc/hosts
-P switches to the PCRE2 engine. Required for: lookaheads, lookbehinds, backreferences, \K, atomic groups. Slower than the Rust engine but feature-complete. Must be compiled with PCRE2 support — verify with rg --pcre2-version.
# Positive lookahead — match 'include' only when followed by '::partial'
rg -P 'include(?=::partial)' ~/atelier/_bibliotheca/domus-captures/docs/modules/ROOT/pages/codex/grep/basics.adoc
# Negative lookahead — match 'include' NOT followed by '::partial'
rg -P 'include(?!::partial)' ~/atelier/_bibliotheca/domus-captures/docs/modules/ROOT/pages/codex/grep/basics.adoc
Lookaheads assert what follows the match without consuming it. (?=X) succeeds if X follows. (?!X) succeeds if X does NOT follow. Both require -P.
# Positive lookbehind — match port numbers preceded by ':'
rg -Po '(?<=:)\d+' /etc/services | head -10
# Negative lookbehind — match digits NOT preceded by ':'
rg -Po '(?<!:)\b\d{2,5}\b' /etc/services | head -10
Lookbehinds assert what precedes the match. (?⇐X) succeeds if X precedes. (?<!X) succeeds if X does NOT precede. PCRE2 supports variable-length lookbehinds — the Rust engine does not support lookbehinds at all.
cat <<'EOF' > /tmp/rg-unicode-test.txt
cafe and cafe with accents
100 items, precio: 50, numero: 42
EOF
rg '\p{L}+' /tmp/rg-unicode-test.txt -o | head -10
\p{L} = any Unicode letter. \p{N} = any Unicode number. \p{S} = symbols. \p{P} = punctuation. The Rust engine supports these natively — no -P required. Superior to [a-zA-Z] for international text.
rg -Po '(?P<key>\w+)=(?P<val>[^ ]+)' -r '${key} -> ${val}' <<'EOF'
host=modestus-aw port=22 user=evan
EOF
Expected output:
host -> modestus-aw
port -> 22
user -> evan
Named captures (?P<name>…) work with -r to restructure matched text. ${name} in the replacement references the named group. Requires -P for named groups.
cat <<'EOF' > /tmp/rg-greedy-test.txt
<tag>first</tag><tag>second</tag>
EOF
# Greedy — matches everything between first < and last >
rg -o '<.*>' /tmp/rg-greedy-test.txt
# Non-greedy — matches each tag individually
rg -o '<.*?>' /tmp/rg-greedy-test.txt
Greedy output: <tag>first</tag><tag>second</tag> (one match).
Non-greedy output: <tag>, first, </tag>, <tag>, second, </tag> — actually <.*?> yields <tag>, </tag>, <tag>, </tag> (four matches). Default quantifiers are greedy. Append ? to make them non-greedy.
# Character class — match vowels
rg '[aeiou]{3,}' /usr/share/dict/words | head -5
# Alternation — match either pattern
rg 'ERROR|WARN' /tmp/rg-greedy-test.txt 2>/dev/null || echo "No matches (expected — test file has no logs)"
# Practical alternation against real content
rg 'include::|xref:' ~/atelier/_bibliotheca/domus-captures/docs/modules/ROOT/pages/codex/grep/index.adoc
Character classes […] and alternation A|B work in the default Rust engine. No -P needed. Alternation is evaluated left to right; first match wins.