POSIX Regex Reference

POSIX BRE and ERE syntax compared side-by-side with grep, sed, awk flavor notes

Searchable POSIX regular expression reference comparing Basic and Extended syntax. See how grouping, alternation, quantifiers and bracket character classes differ between BRE and ERE, plus which flavor grep, sed and awk use. It runs free in your browser on Gera Tools, with nothing uploaded.

Last updated Source: Gera Tools

What is the difference between BRE and ERE?

Basic Regular Expressions (BRE) treat characters like the pipe, plus, question mark, braces and parentheses as literals unless backslash-escaped. Extended Regular Expressions (ERE) treat those same characters as metacharacters directly. BRE is the older POSIX form used by default in grep and sed.

POSIX defines two regular-expression dialects — Basic (BRE) and Extended (ERE) — and the difference between them trips up almost everyone who moves between grep, sed and awk. The same pattern can mean completely different things depending on which flavor a tool uses by default. This reference puts the two dialects side by side, lists the standard bracket character classes, and tells you which tool speaks which dialect.

BRE and ERE: the two POSIX dialects

In a Basic Regular Expression the special characters that do grouping, alternation and counting are written with a leading backslash: grouping is \( \), alternation is \|, and a bound is \{m,n\}. Without the backslash those characters are literal. In an Extended Regular Expression the same constructs are written bare — ( ), |, {m,n} — and a backslash makes them literal instead. The anchors ^ and $, the dot ., the star *, and bracket expressions [...] behave the same in both dialects.

POSIX has no single-letter shorthand classes. Instead it provides named bracket character classes like [:alpha:], [:digit:] and [:space:], which must appear inside a bracket expression — so a digit is [[:digit:]]. This keeps matching correct across locales and character sets where the ASCII ranges alone would be wrong.

BRE vs ERE at a glance

FeatureBREERE
Grouping\( \)( )
Alternation| (GNU ext.)`
One-or-more\+ (GNU ext.)+
Zero-or-one\? (GNU ext.)?
Bounds\{m,n\}{m,n}
Literal brace{\{
Backreferences\1 through \9not in strict POSIX

Tool flavor defaults

ToolDefault dialectOverride flag
grepBRE-E for ERE, -P for PCRE (GNU)
sedBRE-E (GNU/macOS) or -r (older GNU)
awkEREno flag needed
egrepEREdeprecated alias for grep -E
find -regexEmacs RE (BRE-like)-regextype posix-extended

POSIX bracket character classes

These are the portable alternatives to PCRE shorthand classes like \d and \w:

[[:alpha:]]   letter (locale-aware)
[[:digit:]]   0-9
[[:alnum:]]   letter or digit
[[:space:]]   whitespace (space, tab, newline, etc.)
[[:upper:]]   uppercase letter
[[:lower:]]   lowercase letter
[[:punct:]]   punctuation
[[:blank:]]   space or horizontal tab only
[[:print:]]   printable characters
[[:graph:]]   printable, non-space characters

Tips and notes

Remember the tool defaults: grep and sed are BRE unless you pass -E, while awk and egrep are ERE. GNU adds convenience extensions (such as \+ and \? in BRE) that are not portable to other Unixes, so a script that must run anywhere should stick to the strict POSIX forms shown in the table. Also note that POSIX does not guarantee backreferences in ERE — they work in GNU awk and most Linux implementations but are not part of the standard, so for truly portable scripts use BRE when you need \1.

Worked example: the same match in three tools

Suppose you want to match a line containing error or warning followed by a colon. The pattern differs by tool because of the flavor each defaults to:

grep     'error:\|warning:'      file    # BRE — alternation must be escaped (GNU)
grep -E  'error:|warning:'       file    # ERE — bare pipe
sed -n   '/\(error\|warning\):/p' file   # BRE — escaped grouping + alternation
awk      '/error:|warning:/'     file    # ERE — bare metacharacters

Every one of these expresses the same regular language; only the escaping convention changes. This is the single most common reason a pattern that “worked in awk” fails when pasted into plain grep.

Portability checklist

  • Prefer bracket classes ([[:digit:]]) over PCRE shorthands (\d) — the latter is silently literal in a strict POSIX engine.
  • Do not rely on non-greedy quantifiers (*?, +?): POSIX regex is always greedy.
  • Anchors ^ and $ match string start/end, not line boundaries, unless the tool processes input line by line (as grep, sed and awk do by default).
  • When a script must run on both GNU and BSD/macOS userlands, test on both — sed -E is portable but sed -r is GNU-only.

Sources