Vim - 通过正则表达式搜索和替换的增量编号

时间:2014-10-31 18:51:09

标签: regex vim emacs increment substitution

我有这段代码:

array ('id' => 1, 'name' => "Murka", 'date_of_birth' => "2014-10-31", "breed_id" => 1),
array ('id' => 1, 'name' => "Jurka", 'date_of_birth' => "2014-11-31", "breed_id" => 2),
array ('id' => 1, 'name' => "Nyash", 'date_of_birth' => "2014-12-31", "breed_id" => 3),
array ('id' => 1, 'name' => "Meowy", 'date_of_birth' => "2014-01-31", "breed_id" => 4),
array ('id' => 1, 'name' => "Yummi", 'date_of_birth' => "2014-10-31", "breed_id" => 2),
array ('id' => 1, 'name' => "Barss", 'date_of_birth' => "2014-05-31", "breed_id" => 2),
array ('id' => 1, 'name' => "Nonam", 'date_of_birth' => "2014-05-31", "breed_id" => null

我想要更改所有'id' => 1(第1个除外),因此数字会增加1.使用Emacs很容易实现:

M-x replace-regexp
\(1,\)
\,(1+ \#),

如上所述here。经过一些研究后,我用Vim达到的最大值是(灵感来自here):

:let i=1 | g/1,/ s//\=i/ | let i+=1

但这会删除以下所有逗号:

array ('id' => 1 'name' => "Murka", 'date_of_birth' => "2014-10-31", "breed_id" => 1),
array ('id' => 2 'name' => "Jurka", 'date_of_birth' => "2014-11-31", "breed_id" => 2),
array ('id' => 3 'name' => "Nyash", 'date_of_birth' => "2014-12-31", "breed_id" => 3),
array ('id' => 4 'name' => "Meowy", 'date_of_birth' => "2014-01-31", "breed_id" => 4),
array ('id' => 5 'name' => "Yummi", 'date_of_birth' => "2014-10-31", "breed_id" => 2),
array ('id' => 6 'name' => "Barss", 'date_of_birth' => "2014-05-31", "breed_id" => 2),
array ('id' => 7 'name' => "Nonam", 'date_of_birth' => "2014-05-31", "breed_id" => null),

所以我必须解决它(我知道这很容易)。

我知道this和宏,我只是想知道Vim中是否有任何单行命令解决方案。

更一般的问题:在Vim中是否可以注入一些逻辑,如条件语句,操纵正则表达式反向引用? Emacs中的示例如下:

C-M-% \(^.*\)\(linear-gradient(\)\(to right\|to bottom\)\(.*$\) <RET>
\& C-q C-j
\1-prefix-\2\,(if (equal "to right" \3) "left" "top")\4

这个让我在大约一年前的时间里帮助我重构了一些具有大量内联CSS的可怕的HTML代码。

3 个答案:

答案 0 :(得分:4)

我对你的一般性问题没有答案,但我确实有一个针对你的具体情况。您可以通过将逗号置于正面预测中来使命令工作,如下所示:

:let i=1 | g/1(\,\)\@=/ s//\=i/ | let i+=1

现在它只会替换1

答案 1 :(得分:3)

一个非常简单的解决方案:

:%norm f1s^R=line('.')^M

获得如下:

:%norm f1s<C-v><C-r>=line('.')<C-v><CR>

如果您不熟悉在命令行上键入完整的宏,则可以通过录制获得相同的结果:

qq
f1s<C-r>=line('.')<CR>
q
[range]@q

答案 2 :(得分:0)

另一种方法。转到第二行,将光标放在第一行上,现在开始可视块选择 Ctrl-v ,按admin.system.users直到要增加的行,然后按 g < / kbd> Ctrl-a