![sed 中的反向引用如何匹配?](https://linux22.com/image/39625/sed%20%E4%B8%AD%E7%9A%84%E5%8F%8D%E5%90%91%E5%BC%95%E7%94%A8%E5%A6%82%E4%BD%95%E5%8C%B9%E9%85%8D%EF%BC%9F.png)
我在此站点上找到了一个单行sed
命令,它可以删除$PATH
.有一个概念我无法理解。它使用匹配部分中保存的匹配来检测重复项,然后将匹配替换为\1\2
。
在下面的例子中,我不明白为什么\1
并不总是 1111
。测试用例显然表明\1
匹配在模式空间中进一步进行,但我不明白为什么。
sed
脚本 (sed_cmd
):
p #debug
:b
s/[:;]\([^:;]*\)\([:;].*\)[;:]\1/;y\1yx\2x/p
s/[yx]//g #debug remove the field indicators for the next pass
s/;/:/g #debug
tb
s/^\([^:]*\)\(:.*\):\1/\1\2FixedFirst/
aDone
测试命令+输出:
echo "0000:1111:2222:3333:4444:1111:2222:3333:0000" | sed -f sed_cmd
0000:1111:2222:3333:4444:1111:2222:3333:0000
0000;y1111yx:2222:3333:4444x:2222:3333:0000
0000:1111;y2222yx:3333:4444x:3333:0000
0000:1111:2222;y3333yx:4444x:0000
0000:1111:2222:3333:4444FixedFirst
Done
答案1
替代命令中的模式是:[:;]\([^:;]*\)\([:;].*\)[;:]\1
。注意\1
最后的。这意味着与第一组匹配的任何文本\([^:;]*\)
也必须出现在模式的末尾。
您的模式空间最初是0000:1111:2222:3333:4444:1111:2222:3333:0000
.该模式匹配:1111:2222:3333:4444:1111
, 并1111
匹配第一组和\1
最后的 。
经过第一轮替换后,模式空间为改变了到0000:1111:2222:3333:4444:2222:3333:0000
。现在,如果1111
使用模式空间中的 来匹配\([^:;]*\)
,则没有1111
剩余可匹配的\1
。因此,模式无法匹配,正则表达式引擎会尝试其他操作。在这种情况下,使用第一组的下一个可用匹配 是2222
有效的。