在vim脚本/函数中迭代匹配的最简单/最优雅的方法是什么?

Ren*_*ger 4 vim

我正在寻找一个优雅的解决方案(在vim脚本中)迭代缓冲区中正则表达式的所有匹配.那会是这样的

fu! DoSpecialThingsWithMatchedLines()

  for matched_line_no in (GetMatchedPositions("/foo\\>.*\\<bar"))
      let line = getline(matched_line_no)
      call DoItPlease(line)
  end for

endfu
Run Code Online (Sandbox Code Playgroud)

有这样的事吗?我不一定在寻找一个完整的解决方案,任何指引我正确方向的指针都可以.

谢谢/雷内

mic*_*ael 5

你可以使用:他:全球例如.

 :%g/foo\\>.*\\<bar/call DoItPlease(getline("."))
Run Code Online (Sandbox Code Playgroud)

vimscript示例:

fun! Doit(line)
    echo a:line
endfun


fun! MyDo()
    %g/foo/call Doit(getline("."))
endfun

:call MyDo()
Run Code Online (Sandbox Code Playgroud)


Luc*_*tte 5

大多数时候我会使用迈克尔的解决方案 :global

filter(getline('1','$'), 'v:val =~ "foo\\>.*\\<bar"')如果你真的想使用,你也可以玩:for

否则,您可以简单地search()循环调用。

编辑:9 年后,在脚本中,我现在使用map()+filter()

:call map(filter(getline('1','$'), 'v:val =~ "foo\\>.*\\<bar"'), 'DoItPlease(v:val)')
Run Code Online (Sandbox Code Playgroud)

这个:

  • :for基于解决方案快得多,
  • 调试起来要友好得多(鉴于今天的 Vim 脚本集成调试器)
  • 保持各种寄存器/历史不变