在可视块模式下限定高亮区域的 Vim 搜索和替换

27

我经常有列中的文本,并需要替换一些内容,而不会在同一行上破坏类似的文本...以下是一个简单的示例:

vim visual block-mode screenshot

假设我已经使用vim视觉块模式将文本突出显示为灰色,并想将80替换为81;但是,我只想在突出显示的视觉块内进行替换。

我已经尝试过Cntlv : s/80/81/g; 但是,它会替换视觉块内和外部的文本。(根据兰迪的反馈,这是因为: s是一个逐行命令)。

我知道我可以在这种特定情况下使用逐行视觉块替换(Shiftv: s/80\.1/81.1/g);但是,我正在尝试找到一般解决方案,以解决在非逐行视觉块内进行替换的问题(这难道不是视觉块模式应该帮助解决的问题吗?)。需要确认的答案,例如: s/80/81/gc,不是我要找的。

为了清晰起见,我将重新说明问题:如何使用vim的视觉块模式突出显示来替换8081


对于那些在 MS Windows 下使用 gvim 的人,FYI... 可视块模式是 <cntl-q>,因为 <cntl-v> 是粘贴复制缓冲区。 - Mike Pennington
3个回答

28

您需要在模式中添加\%V。根据:help \%V

Match inside the Visual area.  When Visual mode has already been
stopped match in the area that gv would reselect.
This is a /zero-width match.  To make sure the whole pattern is
inside the Visual area put it at the start and end of the pattern.

编辑:明确的解决方法是使用: s/\%V8\%V0/81/g


正好是我要找的;有趣的是在行块模式中我不需要\%V - Mike Pennington
2
因为':s'是一种逐行操作。添加这个的好处是,即使您离开了可视模式,仍然可以使用模式中的'%V'对最后一个可视选择进行操作。 - Randy Morris
为了理解这个,我将\%视为正则表达式转义字符,\V视为\b中的b,表示单词边界,其中\%V是选择的边界。 - Yzmir Ramirez
2
@YzmirRamirez 这种理解\%V的方式是完全错误的。\%V是一个零宽度原子,可以匹配可视选择内部。如果您选择一个字符(例如1)并使用\%V1\%V,您会发现没有匹配,因为第二个字符不在选择范围内。另外,如果它边界,则在选择123上使用\%V2将无法匹配2 - ZyX
@MikePennington,如上所述,您的编辑是不正确的。正确的正则表达式是\%V8\%V0,而不是\%V80\%V - ZyX

7

可视化选择块应该用 %V 进行标识。该块与搜索和替换相关联。

:'<,'>s/\%V80/81/g

6
解决方案显然是\%V正则表达式原子,但请注意,这仍然有点有bug。
更新:这不是bug。这个thread解释了这种行为。

1
谢谢您的回复。您在使用“%V”时遇到了什么样的错误行为? - Mike Pennington
@ChristianBrabandt 如果您能够a)说明\%V在正则表达式中匹配(请参见我对被接受答案的评论),并且b)删除或撤回上面的评论,该评论声明\%V不是零宽度,那将更有帮助。我认为是您的编辑使得这个问题出现在RSS中。 - ZyX

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