sed 可移植性:扩展正则表达式与反斜杠

sch*_*ity 0 sed posix regular-expression portability

我们可以用两种方式编写下一个命令:

# using extended regex
$ echo foobar | sed -E 's/(foo)(bar)/\2\1/'
barfoo
Run Code Online (Sandbox Code Playgroud)

和:

# using backslashes
$ echo foobar | sed 's/\(foo\)\(bar\)/\2\1/'
barfoo
Run Code Online (Sandbox Code Playgroud)

使用反斜杠意味着该命令比扩展正则表达式更可移植?

Qua*_*odo 5

是的

\n

当前的 POSIX 标准sed未指定启用-E扩展正则表达式 (ERE) 的标志。仅此一点就足以得出结论:基本正则表达式 (BRE) 形式\'s/\\(foo\\)\\(bar\\)/\\2\\1/\'是最可移植的。

\n

但是,即使-E包含了sed\'s standard\xe2\x80\x94并且它将是\xe2\x80\x94,正则表达式文档 不会在 ERE 中定义反向引用,因此BRE \\(...\\) == ERE (...)关联本身是 GNU 扩展,而不是保证得到所有程序的支持。例如,POSIX Grep-E包含该标志,但是虽然其中的每一个

\n
grep \'ee*\'\ngrep -E \'e+\'\ngrep \'\\(.\\)\\1\'\n
Run Code Online (Sandbox Code Playgroud)\n

是合规的,

\n
grep -E \'(.)\\1\'\n
Run Code Online (Sandbox Code Playgroud)\n

不是。

\n

同样,有报告具体说明 BSD 不遵循扩展:

\n
\n

[在 FreeBSD 中]sed -E \'/(.)\\1/d\'删除带有1其他字符的行。

\n
\n

而 GNUsed会将其视为反向引用并删除包含两个相等且相邻字符的行。

\n