我们可以用两种方式编写下一个命令:
# using extended regex
$ echo foobar | sed -E 's/(foo)(bar)/\2\1/'
barfoo
和:
# using backslashes
$ echo foobar | sed 's/\(foo\)\(bar\)/\2\1/'
barfoo
使用反斜杠意味着该命令比扩展正则表达式更可移植?
答案1
是的
这当前的 POSIX 标准sed
未指定-E
启用扩展正则表达式 (ERE) 的标志。仅此一点就足以得出结论:基本正则表达式 (BRE) 形式's/\(foo\)\(bar\)/\2\1/'
是最可移植的。
不过,就算-E
是纳入了sed
标准——它将是-, 这正则表达式文档 没有在 ERE 中定义反向引用,因此该BRE \(...\) == ERE (...)
关联本身是一个 GNU 扩展,不保证所有程序都支持。POSIX 查询,例如,包括-E
标志,但是虽然其中的每一个
grep 'ee*'
grep -E 'e+'
grep '\(.\)\1'
是合规的,
grep -E '(.)\1'
不是。
同样,还有报告具体说明 BSD 不遵循扩展:
[在 FreeBSD 中]删除带有其他字符
sed -E '/(.)\1/d'
的行。1
而 GNUsed
会将其视为反向引用并删除包含两个相等且相邻字符的行。
答案2
sed -E
意味着它将使用扩展正则表达式 ( ERE
),如果没有该标志,它将使用基本正则表达式 ( BRE
)。
并非所有sed
版本都可以处理扩展的正则表达式,所以是的,它更便携,但不是因为您使用了反斜杠。这很正常BRE
。
答案3
GNU 手册给出答案:
5.2 基本(BRE)和扩展(ERE)正则表达式
基本正则表达式和扩展正则表达式是指定模式语法的两种变体。基本正则表达式 (BRE) 语法是 sed 中的默认语法(grep 中也类似)。使用 POSIX 指定的 -E 选项(-r、--regexp-extended)启用扩展正则表达式 (ERE) 语法。
在 GNU sed 中,基本正则表达式和扩展正则表达式之间的唯一区别在于一些特殊字符的行为:“?”、“+”、括号、大括号 (“{}”) 和“|”。
使用基本 (BRE) 语法,这些字符没有特殊含义,除非以反斜杠('\')为前缀;而使用扩展 (ERE) 语法则相反:这些字符是特殊的,除非它们以反斜杠 ('\') 为前缀。