深色模式
BRE 和 ERE 的区别
概述
很多人第一次在 grep 或 sed 里碰到正则,会有一种很别扭的感觉:为什么有时要写 \(,有时又写 (;为什么有时 + 能用,有时又像普通字符。
这不是工具在捣乱,而是因为 POSIX 把正则分成了两套语法:BRE 和 ERE。两者解决的问题相近,但写法和支持范围并不完全一样。
POSIX 为什么要分成两套
BRE 是比较早的一套写法,主要照顾传统 Unix 工具的兼容性。ERE 可以看成是在这个基础上把常见能力写得更直接一些,尤其是分组、选择和次数限定这几块,不再那么依赖转义。
这也是为什么 ERE 虽然经常被叫做“扩展正则”,但它并不等于“现代语言里的所有高级正则”。它只是 POSIX 世界里的另一套语法,不是 PCRE 的别名。
最重要的语法差异
可以先抓住最常用的几项:
| 能力 | BRE 常见写法 | ERE 常见写法 |
|---|---|---|
| 分组 | \\(ab\\) | (ab) |
| 次数限定 | a\\{2,4\\} | a{2,4} |
| 选择 | 通常不直接支持 ` | ` |
| 一次或多次 | 通常没有裸 + | a+ |
| 零次或一次 | 通常没有裸 ? | a? |
最直观的结论是:
BRE写起来更依赖反斜线ERE更接近今天很多人熟悉的写法
例如匹配三次 ab:
text
\(ab\)\{3\}如果换成 ERE,可以直接写成:
text
(ab){3}两者表达的是同一件事,只是语法负担差别很大。
两者能力并不是简单的“谁包含谁”
把 ERE 理解成“BRE 全量升级版”并不准确。更稳妥的说法是:两者覆盖面大量重合,但标准定义和可用语法并不完全一致。
最典型的例子是反向引用。很多人会把“有括号”自动联想到“有捕获组、能回溯引用”。在 POSIX 语境里,这个联想并不可靠。
BRE里有反向引用这个概念ERE标准并不把反向引用当成基础能力- 实际工具是否额外支持,还要看具体实现
所以在 POSIX 工具里看到括号,先把它理解成“分组”,不要立刻把它理解成“现代语言里的捕获组全家桶”。
哪些东西不属于 POSIX 正则的基本盘
下面这些能力,在现代教程里很常见,但不要默认它们属于 BRE 或 ERE:
\d、\w、\s这类快捷字符组- 非贪婪量词,例如
*? - 环视,例如
(?=...)、(?<=...) - 命名分组,例如
(?P<name>...)或(?<name>...)
这些更像 Perl 风格正则或后来各门语言的扩展,不是 POSIX 的基础语法。
如果一篇资料一边讲 BRE、ERE,一边直接把环视和非贪婪也塞进去,读起来当然会乱,因为那已经不是同一个层级的话题了。
什么时候该用 BRE,什么时候该用 ERE
如果只从书写体验看,ERE 更顺手,现代读者也更容易接受。
但实际选择通常不是“喜欢哪种写法”,而是看工具默认行为和兼容目标:
- 追求老工具兼容性时,往往会碰到
BRE - 在
grep -E、sed -E这类明确切到扩展模式的场景里,用的是ERE - 一旦需要环视、命名分组这类更强特性,通常已经超出 POSIX,需要换到别的实现
所以这里最重要的不是死记哪套更强,而是先判断自己现在站在哪个语境里。
可以先记住的结论
BRE和ERE都属于 POSIX 正则ERE不等于 PCRE,也不等于“所有现代正则”BRE和ERE的核心区别,主要体现在语法写法和一部分能力边界- 工具文档如果没写清正则模式,最好不要靠感觉猜
下一篇就把这件事落到常用命令上,看 grep、sed、awk、grep -P 到底各自站在哪一边。
