2014-10-31 109 views
0

我有这样的代码:Vim的 - 通过正则表达式搜索增量编号和替换

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 

这一个帮助我大约一年+前重构一些巨大的可怕的HTML代码,有很多内联CSS的。

回答

4

我没有你的一般问题的答案,但我确实有一个针对你的具体情况。您可以通过将逗号成正先行,这样使你的指挥工作:

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

现在就只能更换1

+0

非常感谢,它的工作原理!添加到我的最爱:) – a1111exe 2014-10-31 19:45:48

+0

你可以使用'\ ze'而不是积极的lookahead来简化你的正则表达式。例如':让我= 1 | g/1 \ ze,/ s // \ = i/| let i + = 1' – 2014-10-31 23:45:39

+0

:let i = 1 | g/1 \ ze,/ s // \ = i/|让i + = 1对我来说真的是充分的。请让我知道是否可以选择线的范围。意味着我只需要替换文件中的10到20行。我们如何指定: – imbichie 2015-03-20 08:04:51

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 
+0

这种方式对我来说有点深奥,但它有效,我一定会试一试。非常感谢你! – a1111exe 2014-10-31 21:29:22