在某些列之间替换所有不匹配的字符

3
我想替换在特定列之间(搜索后)单行中的所有不匹配字符。 示例: 搜索可以是任何内容。 下面的示例中,搜索为test。 非匹配字符的替代字符:空格。
我想替换10列和30列之间不包括“test”的所有字符。 使用|表示第10列和第30列。
before:  djd<aj.testjal.kjetestjaja testlala ratesttsuvtesta !<-a-
                  |                   |   
after:   djd<aj.test       test     testlala ratesttsuvtesta !<-a-

我该如何实现这个?

1
我还没有亲自证明过这一点,但我认为你不能仅凭正则表达式就做到这一点。为了排除前10个字符,你必须以某种方式进行匹配...一旦你进行了匹配,它们就可以进行替换。我认为最好将字符串分成三部分,执行替换,然后在拼接在一起...但我很想被证明是错误的。 - Barton Chittenden
有时候是10个字符,有时候是更多或更少的字符。你怎么把这个字符串分成3段再拼接起来? - Reman
如果我严格地留在vim中,我会在想要断开行的位置添加一个换行符,进行替换,然后再次连接该行。如果这是我经常要做的事情,我会创建一个宏来执行替换和连接行的操作(确保在连接后删除多余的空格)。我也喜欢@Bernhard的方法,但我从未尝试过。 - Barton Chittenden
@Barton:可以使用Vim正则表达式语言和:substitute命令的功能来解决这个问题。 - ib.
2个回答

3
在该行上使用以下替换命令。
:s/\(test\)\zs\|\%>9v\%<31v./\=submatch(1)!=''?'':' '/g

如果使用视觉选择指定列的范围,请运行:

:'<,'>s/\(test\)\zs\|\%V./\=submatch(1)!=''?'':' '/g

非常感谢。我现在已经解决了所有与列有关的事情!只是为了更好地理解,我需要改变什么来做相反的事情...仅在第10行和第30行之间替换test中的字母?我已经尝试了移动\zs和修改其他内容,但都没有成功。非常感谢! - Reman
1
对于补充问题,如果列的范围事先已知,请使用命令 :%s/\%>9vtest\%<32v/\=repeat(' ',strwidth(submatch(0)))/g;如果该范围是通过可视选择指定的,请使用 :'<,'>s/\%Vtes\%Vt/\=repeat(' ',strwidth(submatch(0)))/g - ib.

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接