Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
618 views
in Technique[技术] by (71.8m points)

regex - Vim - incremental numbering via regular expression search and replace

I have this code:

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

I'll want to change all 'id' => 1 (except the 1st) so the number will increment by 1. It's simple to achieve with Emacs:

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

As described here. After some research the maximum that I've been able to achieve with Vim is (inspired from here):

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

But this removes all the following commas:

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),

So I have to fix it (I know it's easy).

I am aware of this and macros, I'm just interested to know if there any one-line command solution in Vim.

More general question: is it possible in Vim to inject some logic like conditional statements, manipulating on regex back references? The example for this in Emacs would be:

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

This one helped me about a year+ ago to refactor some huge scary HTML code that had a much of inline CSS.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I don't have an answer to your general question, but I do have one for your specific situation. You can make your command work by putting the comma into a positive look-ahead, like this:

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

Now it will only replace the 1.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...