如何使用vim脚本仅替换一次模式

如何使用vim脚本仅替换一次模式,vim,Vim,我在vim脚本方面是新手,如何只替换一次模式。我正在使用以下代码 %s/^\\docume.*/\\docment\[STRING\] 输入 \document{A} \document{B} \document{C} \document{D} 预期产量 \document{STRING} \document{B} \document{C} \document{D} 我认为没有什么像样的方法可以做到这一点。我想到的是: 如果在替换命令之前未包含%,则vim仅替换当前行中的第一个匹配项(通过

我在vim脚本方面是新手,如何只替换一次模式。我正在使用以下代码

%s/^\\docume.*/\\docment\[STRING\]
输入

\document{A}
\document{B}
\document{C}
\document{D}
预期产量

\document{STRING}
\document{B}
\document{C}
\document{D}

我认为没有什么像样的方法可以做到这一点。我想到的是:

如果在替换命令之前未包含
%
,则vim仅替换当前行中的第一个匹配项(通过将
/g
添加到命令末尾来替换一行中的所有匹配项)

因此,您可以首先搜索表达式,从而找到它的第一个匹配项,然后执行替换(no
%

我用
execute
命令尝试了这一点(就像运行vim脚本一样),但没有成功

:execute "/foo"|"s/foo/bar/"
但在两个独立的
execute
命令中运行它们确实有效


我猜在
execute
(因此,vim脚本)中的搜索没有正常工作。如果您可以在脚本中找到任何其他方法,让您到达第一次出现的行的开头(我希望您能这样做)然后
s/foo/bar
只会取代第一个。

我认为没有任何合适的方法可以做到这一点。我想到的是:

如果在替换命令之前未包含
%
,则vim仅替换当前行中的第一个匹配项(通过将
/g
添加到命令末尾来替换一行中的所有匹配项)

因此,您可以首先搜索表达式,从而找到它的第一个匹配项,然后执行替换(no
%

我用
execute
命令尝试了这一点(就像运行vim脚本一样),但没有成功

:execute "/foo"|"s/foo/bar/"
但在两个独立的
execute
命令中运行它们确实有效


我猜在
execute
(因此,vim脚本)中的搜索没有正常工作。如果您可以在脚本中找到任何其他方法,让您到达第一次出现的行的开头(我希望您能这样做)然后,
s/foo/bar
将只替换第一个。

您使用的
%
是命令将在其中显示的行范围 已处理,在本例中表示从第一行到最后一行(可以 也可以写成
:1,$s/regex/…

指定的地址也只能是一行,如:

  • :3s/regex/../
    仅在第3行中操作
  • :$s/regex/../
    仅在最后一行操作
搜索也可以用作范围的一部分:
:/search/s/regex/replace/
。但是,正如我们用来 搜索一个文件,它将在当前光标后开始搜索 如果要匹配文件的第一个匹配项,可以 创建移动到第0行(第1行之前),然后执行搜索。它将 找到第一次出现的情况,即使在第1行。因此,您的 问题是使用一个范围(即使它只匹配一行) 在该范围内)

最后的答案不是
:0,/search/
,但是
不会移动您的 光标,以便将第0行与光标后的第一个搜索查找匹配 位置。如果要在您的范围内移动光标,请使用
相反

另一个小技巧是:将范围内的搜索重用为范围内的搜索 替换时,将后者留空。这将给出以下最终答案:

:0;/^\\document\zs.*/s//{STRING}
换句话说:在第0行到第一个匹配的 模式,用
{STRING}
替换相同的模式(因此 仅在一行中,文件的最顶端匹配项)


请查看手册中的范围,以了解更多信息:
:h range

您使用的
%
是命令所在的行范围 已处理,在本例中表示从第一行到最后一行(可以 也可以写成
:1,$s/regex/…

指定的地址也只能是一行,如:

  • :3s/regex/../
    仅在第3行中操作
  • :$s/regex/../
    仅在最后一行操作
搜索也可以用作范围的一部分:
:/search/s/regex/replace/
。但是,正如我们用来 搜索一个文件,它将在当前光标后开始搜索 如果要匹配文件的第一个匹配项,可以 创建移动到第0行(第1行之前),然后执行搜索。它将 找到第一次出现的情况,即使在第1行。因此,您的 问题是使用一个范围(即使它只匹配一行) 在该范围内)

最后的答案不是
:0,/search/
,但是
不会移动您的 光标,以便将第0行与光标后的第一个搜索查找匹配 位置。如果要在您的范围内移动光标,请使用
相反

另一个小技巧是:将范围内的搜索重用为范围内的搜索 替换时,将后者留空。这将给出以下最终答案:

:0;/^\\document\zs.*/s//{STRING}
换句话说:在第0行到第一个匹配的 模式,用
{STRING}
替换相同的模式(因此 仅在一行中,文件的最顶端匹配项)


请查看手册中的范围,以了解更多信息:
:h range

您可以使用搜索作为范围,因此
:/foo/s/foo/bar/
。这将匹配光标行后的第一个
foo
。为了确保它是文档中的第一个匹配,您可以创建从第0行到第一个匹配的范围(即使它是一个范围,也只有一行与替换匹配)。如果使用
:0的范围,/foo/
,它仍然不是答案,因为
不会移动光标,因此匹配将是光标后的第一行。最后的答案是使用