FreeBSD 是否包含多个基本正则表达式的变体?

Sti*_*lez 5 freebsd compatibility regular-expression portability

grep并且sed都被描述为默认使用“基本正则表达式”(“BRE”)。BRE在这里得到了很好的描述。

但考虑这个输出:

# echo '    aaaaa   ' | grep '\(aaaaa\|bbbbb\)'
    aaaaa
# echo '    aaaaa   ' | sed '/\(aaaaa\|bbbbb\)/ s/ /_/g'
    aaaaa
Run Code Online (Sandbox Code Playgroud)

在第一个命令中,\( ... \| ... \)语法显然表现(X OR Y),因为输出通过grep

在第二个命令中,\( ... \| ... \)语法显然没有作为(X OR Y),因为空格没有更改为下划线。

(相比之下,这两个命令都识别\+为“一次或多次重复”)

发生了什么事?为什么在 FreeBSD 中似乎有两种类型的 BRE,其中一种可以识别另一种不能识别的语法?

更深层次的问题是,许多项目都着眼于 BRE 来为其他类 Unix 系统提供可移植性。但这表明即使 BRE 也不太可能跨平台相同,如果它们单个平台甚至不能相同。啊?

ilk*_*chu 9

链接文章中的描述是错误的。

实际的 POSIX 定义指出:

以未转义的 <backslash> ( '\' ) 开头的普通字符的解释未定义,除了[ (){}、数字和括号表达式]

普通字符定义为除 BRE 特殊字符.[^$*和反斜杠本身之外的任何字符。

因此,与该页面声明不同,\+BRE 中的是未定义的,因此\|.

一些正则表达式实现将它们定义为与 ERE 相同+|但尤其是 GNU 实现。但是您不应该指望这一点,而是坚持定义的功能。

当然,这里的问题是 ERE 交替运算符|在 BRE 中根本不存在,而 ERE 的等价物+非常丑陋(它是\{1,\})。所以你可能想改用 ERE。