我有一个文件中包含以下文本
23456789
当我尝试使用命令替换上述文本时,
1,$s/\(\d\)\(\d\d\d\)\(\d\d\)*\>/\3\g
我得到了 89
。应该是 6789
吗?有人能告诉我为什么是 89
吗。
按照你的正则表达式,它会匹配一个数字,然后是三个数字,接着是任意数量的每组两个数字。因此,如果第三个匹配存在,它将始终是两个数字。在你特定的测试用例中,“89”在\4而不是\3。
将正则表达式更改为
1,$s/\(\d\)\(\d\d\d\)\(\d\d\+\)\>/\3\g
由于第三组会捕获两个或更多数字(最多可以是所有数字),因此结果将为“6789”。
1,$s/\(\d\)\(\d\d\d\)\(\%(\d\d\)*\)\>/\3/g
6789
,如果输入改变为...2345678
278
。第三组被定义为2位数字长度。如果您想匹配最后4位数字,则需要使用\(\d\d\d\d\)
,末尾不带*
。如果您只想匹配除前4位以外的所有数字,请将*
放在组匹配内部而不是外部。
我在nvi中尝试了这个命令,但它不起作用。在vim中它可以工作,只是你必须更正g前的最后一个倒置短横线为短横线,像这样:
1,$s/\(\d\)\(\d\d\d\)\(\d\d\)*\>/\3/g
然后它会被替换成89。 原因是你使用*表示最后的\d\d可以重复零次、一次或多次,并且使用>表示结束单词边界。 使用第三组,你要求最后一组,但由于*,最后两个数字(\d\d)是89。 去掉*>,你可以得到6789。像这样:
1,$s/\(\d\)\(\d\d\d\)\(\d\d\)/\3/g
注意 > 符号,它在这里扮演了一个棘手的角色,因为使用以下命令:1,$s/\(\d\)\(\d\d\d\)\(\d\d\)\>/\3
,你会得到 2389 的结果!因为从单词边界的角度来看,dddddd 匹配的是 456789,并被最后两个 dd 替换,即 89。所以你得到了 23+89,让人惊叹!LOL
你可能需要(需要额外的包装组):
%s/\(\d\)\(\d\d\d\)\(\(\d\d\)*\)\>/\3\g
虽然我不确定你为什么要捕获前两个组。