sed 中的反向引用如何匹配?

sed 中的反向引用如何匹配?

我在此站点上找到了一个单行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有效的。

相关内容