====== Regular Expressions ======
Same pattern means different things in different tools. This is the table
that resolves it.
===== Regex Flavors by Tool =====
^ Tool ^ Default ^ Upgrade flag ^
| ''grep'' | BRE | ''-E'' for ERE, ''-P'' for PCRE |
| ''sed'' | BRE | ''-E'' (or ''-r'') for ERE |
| ''awk'' | ERE-ish | gawk has more |
| ''rg'' | Rust regex | no backrefs or lookaround |
| ''perl'' | PCRE | |
| [[ =~ ]] in bash | ERE | |
===== The Differences That Matter =====
^ Feature ^ BRE (grep/sed default) ^ ERE (''-E'', awk, bash ''=~'') ^
| ''+'', ''?'' quantifiers | ''\+'', ''\?'' (escaped = special) | bare ''+'' ''?'' |
| groups | ''\( \)'' | ''( )'' |
| alternation | ''\\|'' | ''|'' |
| ''{n,m}'' counts | ''\{n,m\}'' | ''{n,m}'' |
| backrefs in pattern | ''\1'' | ''\1'' for ERE search; not in rg |
Escaped-vs-bare flips between BRE and ERE: in BRE, ''(a)'' is literal parens
and ''\(a\)'' is a group; in ERE it's the opposite. **When unsure, use ''-E''.**
===== Universal building blocks =====
. any char \. literal dot
* + ? 0+, 1+, 0-1 ^ $ line start/end
[abc] set [^abc] negated set
[a-z] range {n,m} counts: {3} {2,} {2,5}
x|y alternation (ERE) (x|y) group
POSIX classes (work everywhere, even BRE):
[[:digit:]] [[:alpha:]] [[:alnum:]] [[:space:]] [[:upper:]] [[:lower:]]
[[:punct:]] [[:print:]] [[:blank:]] [[:xdigit:]]
GNU extras (work in GNU grep/sed both flavors): ''\b'' word boundary,
''\<''/''\>'' word edges, ''\w'' word char, ''\s'' whitespace, ''\B''.
PCRE/Rust extras (''grep -P'', ''rg'', perl): ''\d \D \s \S \w \W'',
non-greedy ''*?'', named groups ''(?P..)'', lookahead ''(?=..)'' ''(?!..)''.
**Note:** ''rg'''s default engine supports NO lookaround/backrefs: add
''rg -P'' to get PCRE2 when you need them.
===== Practical translations =====
# same task, three tools
grep -E '^(Mon|Tue)' f sed -nE '/^(Mon|Tue)/p' f rg '^(Mon|Tue)' f
# BRE version of the ERE "(a|b)+"
grep 'x\(a\|b\)\+y' # hard to read: use -E instead
# IPs: ERE
grep -oE '[0-9]{1,3}(\.[0-9]{1,3}){3}'
# BRE equivalent (don't do this)
grep -o '[0-9]\{1,3\}\(\.[0-9]\{1,3\}\)\{3\}'
===== Substitution notes =====
* sed backrefs in replacement: ''\1''-''\9'', ''&'' = whole match.
* rg capture replace: ''rg 'a(\d+)' -r 'num$1''' uses ''$1''.
* Case transforms (GNU sed): ''sed 's/\(.*\)/\U\1/''' uppercases.
===== When Regex Fails =====
* Pattern has ''|''/''(''/''{'' and you did not mean regex: ''grep -F''.
* Greedy ''.*'' matched too much: use ''[^x]*'' or PCRE ''.*?''.
* Matching across lines: ''grep -z'', ''perl -0777'', or awk paragraph mode.
Line-oriented tools will not do it with ''$''/''.'' alone.
===== See Also =====
* [[terminal:scripting:start|Scripting Index]]
* [[terminal:tools:start|CLI Tools]]
* [[terminal:start|Return to terminal]]
* [[start|Return to wiki home]]