Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/vim/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
VIM搜索/替换模式_Vim - Fatal编程技术网

VIM搜索/替换模式

VIM搜索/替换模式,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 &

如何在以下情况下执行VIM搜索/更换:

a) 该行包含str1

b) 该行还包含str2

c) 该行不包含str3


在这样一行中,我确实想用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