VIM搜索/替换模式
如何在以下情况下执行VIM搜索/更换: a) 该行包含str1 b) 该行还包含str2 c) 该行不包含str3VIM搜索/替换模式,vim,Vim,如何在以下情况下执行VIM搜索/更换: a) 该行包含str1 b) 该行还包含str2 c) 该行不包含str3 在这样一行中,我确实想用yyy替换xxx,但regex处理的能力不强。有很多方法可以做到这一点,但有点棘手。一个非常简单的函数可以解决您的问题: function! Rep() let l = getline('.') if stridx(l, 'str1')>=0 && stridx(l,'str2') >=0 &
在这样一行中,我确实想用yyy替换xxx,但regex处理
的能力不强。有很多方法可以做到这一点,但有点棘手。一个非常简单的函数可以解决您的问题:
function! Rep()
let l = getline('.')
if stridx(l, 'str1')>=0 && stridx(l,'str2') >=0 && stridx(l,'str3')<0
execute 's/xxx/yyy/g'
endif
endfunction
将改为:
str1 str2 str3 xxx
str3 str2 xxx
str2 xxx
*str1 str2 yyy
*yyy str2 yyy str2 yyy str1
我认为将str1、str2、xxx、yyy替换为该函数中的实际值对您来说并不难,是吗
编辑
你真正的问题似乎比你在问题中描述的问题要容易得多。试试这句话:
:%s/\(\s*return\s*aLib\.[^(]\+(\)\s*\()\)/\1aHandle\2/
请注意,它可以写得更短,仅用于您的示例工作,但我希望它是安全的 这将替换包含字符串return
和字符串aLib
的文件中每一行中的()
字符串,之后的某一点:
:%s/return.*aLib.*\zs()\ze/(aHandle)/
%
是命令的操作范围,包括文件中的所有行
\zs
表示替换字符串的开始,而\ze
表示其结束
如果每行必须替换多个实例,请在最后一个/
之后的命令末尾添加g
。如果您希望确认每个替换,请在末尾添加c
标志
假设()
字符串在有andle
的情况下不存在,则此命令不会准确回答您的问题,但根据注释中提供的示例,这可能符合您的需要。我认为@Kent的答案(函数)在执行复杂搜索/替换时是“最正确的”。之后更容易修改,也更容易理解,写起来也比这快。但我认为,如果有可能用“一行”来实现这一点,那会很有趣。
我欢迎关于这不起作用的评论,如果可能的话,我自己也觉得很有趣,如果这是“最佳解决方案”,则不
原始问题中描述的所有情况的“一行”
:v/str3/s/\v(.*str1&.*str2)@=.{-}\zsxxx/yyy/g
说明:
:v/str3/
所有不包含“str3
”的行
s/
替换
\v
“非常神奇”(不必转义像{}
这样的正则表达式)
(.*str1和.*str2)@=
积极前瞻,
*str1
任何字符0或更多(“贪婪”)后跟“str1
”,前面的*
对于&
和@=
都很重要
&
必须存在&
前后的模式,不同于使用“or”的
,两个模式必须从同一个位置开始,这就是为什么在str1/2
之前使用*
@=
前面的原子(在括号中)应该存在,但是模式不包括在匹配中,但是原子必须从行的开头开始才能工作(*
确保这一点)
{-}
任何字符0或更多(“非贪婪”),{-}
而不是*
是很重要的,如果需要替换多个xxx
(在这种情况下,g
标志不够)
\zs
设置匹配的开始(替换内容)
xxx
最后,要替换的字符串
/yyy/
将匹配项替换为yyy
g
线路上的所有事件
这与使用@Kent答案中的示例得到的结果相同,它将处理任意顺序的str1
、str2
、str3
和xxx
我重申,如果出于某种原因某个函数不是备选函数,则这是一个备选函数。据我所知,OP,例如,在他的情况下,str2
总是在str1
之后,因此这是一种更通用的解决方案,适用于此类情况(可能更符合学术兴趣)。最好发布示例输入和所需输出。可能有一种比你想的更简单的方法。好的,这里有一个输入行:return aLib.getSomething()。该行需要变成return aLib.getSomething(aHandle)。关于这个问题,str1是“return”,str2是“aLib”。str3是“aHandle”,替换字符串是“()”。我需要替换这些模式中的许多模式。我将做出一个可能不正确的假设,并假设您只是点击enter键,试图在您的评论中输入换行符。按住shift键的同时按enter键在注释中插入换行符。只是确认一下,字符串的顺序是否始终相同?可以假定顺序始终相同,是的。哪里是而不是str3
部分?e、 我的字符串是return aHandle.aLib()
?我会试试看。事实上,如果该行包含a(),它就不包含str3,所以它应该可以工作..这是我的推理。我已经修改了我的答案,以便更清楚地了解命令在这方面的行为。@Evantietelman这也适用于他的真实输入。它应该是通用的解决方案。秩序不重要,我知道。你的答案的多才多艺使它变得优秀。你真正的问题似乎比你问题中的问题容易得多。在回答中选中“编辑”。
:v/str3/s/\v(.*str1&.*str2)@=.{-}\zsxxx/yyy/g