2014-10-31 69 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