Vim如何制作:g与zs匹配正常工作

时间:2014-07-07 05:52:27

标签: regex vim

我在我的文件顶部有这个:

var server = require('http');
var watchr = require('watchr');
var io = require('socket.io');
var fs = require('fs');

我想把这个垃圾变成一个合适的var列表:

var server = require('http'),
    watchr = require('watchr'),
    io = require('socket.io')(server),
    fs = require('fs');

所以我的第一步是在本段中找到除第一个之外的所有var声明并缩进它们。因此,我搜索前一行中另一个var之前的每个单词var

这是由于某种原因起作用的正则表达式:

\vvar\_.{-}\zs<(var)@>

说明:

\v          Very magic mode (make all special characters special)
var         The word var
\_          Spanning multiple lines
.           Any charaacter
{-}         Non greedy
\zs         Actually start higlighting our search here
<           A word boundary
(var)       The second occurance of the word var
@>          Treat the previous thing (var) as the whole match. Otherwise
                 Vim is too stupid to match consecutive lines and only
                 matches every other line

现在当我在我的文件中点击 n 时,Vim正确地跳转到每个var语句,除了第一个。耶!

现在让我们使用我们可靠的:g命令在匹配我们上一个正则表达式的所有行上运行一个命令(除了第一个正则表达式之外的所有行,因为 n 跳过第一个正则表达式)

v i p 然后:

'<,'>g//norm>>

现在我明白了:

    var server = require('http');
    var watchr = require('watchr');
    var io = require('socket.io');
    var fs = require('fs');

是什么给出的?为什么它缩进我的第一行?如何让gzs@>或任何令人恐惧的Vim正则表达式完美匹配?

1 个答案:

答案 0 :(得分:3)

:global只会获取多行匹配的第一行,除非您为执行的命令赋予偏移量:

:g/^var/+norm >>

结果:

var server = require('http');
    var watchr = require('watchr');
    var io = require('socket.io');
    var fs = require('fs');

无论如何,我建议采用这种更简单的方法:

  1. 将该段落加入一行:

    vipJ or :'{,'}j<CR>
    

    结果:

    var server = require('http'); var watchr = require('watchr'); var io = require('socket.io'); var fs = require('fs');
    
  2. 使用正确的字符串在正确的位置拆分该行:

    :s/; var /,\r    /g
    

    结果:

    var server = require('http'),
        watchr = require('watchr'),
        io = require('socket.io'),
        fs = require('fs');