sed反向引用仅匹配捕获组首字符问题排查
问题解答
问题1:为何sed -r 's/(SomeText[0-9]+)\.\1/\1/'在macOS/Alpine sed中无效?
macOS和Alpine使用的是BSD分支的sed,-r选项是为兼容GNU sed添加的非原生选项,并非BSD sed原生支持的扩展正则模式。BSD sed原生启用扩展正则的选项是-E,-r模式下对POSIX扩展正则的反向引用解析存在兼容性问题,导致捕获组的反向引用\1无法正确匹配对应内容,因此命令无效果。
问题2:为何sed -r 's/SomeText([0-9]+)\.SomeText\1/SomeText\1/'替换后出现SomeText155?
这是BSD sed-r兼容模式的解析异常导致的:在该模式下,替换字段中的反向引用\1未被正确解析为第一个捕获组的完整内容(即15),而是出现解析错误,最终导致替换结果异常。
正确解决方案
改用BSD sed原生的-E选项启用扩展正则,命令如下:
sed -E 's/(SomeText[0-9]+)\.\1/\1/' myfile
该命令会正确匹配SomeTextXX.SomeTextXX格式的内容,并替换为SomeTextXX。
如果需要兼容不支持-E的环境,也可以使用基本正则(BRE)写法(注意括号和+需要转义):
sed 's/\(SomeText[0-9]\+\)\.\1/\1/' myfile
内容的提问来源于stack exchange,提问作者m02ph3u5
相关产品推荐
相关产品推荐

