在外部命令中使用匹配模式

时间:2014-02-04 17:41:15

标签: regex vim

我想在vim中定义一个映射,它在文件中搜索一个特殊的位置(使用正则表达式),然后执行一个取决于匹配模式的外部命令。即我在想类似的事情:

:g/set\ "\(.*\)"/!echo 'bla '\1' blubb' > file

:g:set\ "\(.*\)":call system("echo 'bla ". submatch(0) ." blubb' > file")

我的目标是在我的文件中搜索类似

的行
set "x=3"

并使用内容创建新文件:

bla x=3 blubb

不幸的是,两次尝试(以及其他几次尝试)都无效。谢谢!

编辑:将以下内容添加到我的.vimrc也不起作用:

:map <F4> :g:set\ "\(.*\)":call Gnutex(submatch(1))
function Gnutex(str)
   return system("echo 'bla ". a:str ." blubb' > file")
endfunction

编辑: 工作解决方案(连同之前的功能):

:% s/set\ output\ "\(.*\)"/\=[submatch(0), Gnutex(submatch(1))][0]/

我认为有更好的解决方案,但这很有用。

1 个答案:

答案 0 :(得分:3)

\1submatch(0)表达式作为:s命令的一部分提供。它们不会自动用于:g命令。

这样的东西
:g/set ".*"/execute "!echo 'bla" matchstr(getline("."), 'set "\zs.*\ze"') "blubb' > file"

应该有效。 (我测试时没有“&gt;文件”部分。)

请注意,您不必将“”(空格)作为正则表达式的一部分进行转义。

关键是:g/<pattern>/之后的部分应该是一个可以做你想做的ex命令。在这种情况下,我使用getline()获取当前行,使用matchstr()(更简单但灵活性低于substitute())和:execute结果。

您应该可以使用:call system()执行类似操作。

我认为:g设置了搜索注册,因此您可以避免在@/matchstr()调用中使用substitute()两次写出正则表达式。在上面的示例中,我删除了\(分组\)个字符,但如果您想尝试这种方法,则应该恢复它们。