macOS中sed扩展正则表达式地址里如何使用反向引用?
macOS sed扩展正则地址中反向引用的问题解决与说明
问题重现
在macOS 12.4的sed中,使用基础正则表达式时,地址部分的反向引用可以正常工作:
% echo -e 'Foo,Foo\nFoo,Bar' | sed '/\(Foo\),\1/s//__SAME__/' __SAME__ Foo,Bar
但启用扩展正则表达式(-E参数)后,地址部分的反向引用失效:
% echo -e 'Foo,Foo\nFoo,Bar' | sed -E '/(Foo),\1/s//__SAME__/' Foo,Foo Foo,Bar
而同样的命令在GNU sed 4.8中可以正常执行。
实现修改方案
要在macOS sed的扩展正则模式下实现相同效果,无需单独用地址正则匹配,直接把匹配逻辑整合到替换命令的正则表达式中即可:
% echo -e 'Foo,Foo\nFoo,Bar' | sed -E 's/(Foo),\1/__SAME__/' __SAME__ Foo,Bar
这种写法既利用了扩展正则的简洁语法(捕获组无需转义()),又能正常触发反向引用的匹配。
差异原因说明
这种行为差异不属于bug,而是BSD系sed(macOS sed基于此)与GNU sed的实现特性区别:
- GNU sed对扩展正则的支持更统一,地址部分和替换部分的正则语法规则一致,都支持反向引用;
- BSD sed在启用
-E后,地址部分的正则处理逻辑与替换部分不同,不支持在地址正则中使用反向引用,这是历史实现上的差异,而非功能缺陷。
内容的提问来源于stack exchange,提问作者hisakatha
相关产品推荐
相关产品推荐

