regexvimnumber-sequence

gVim insert serial number before each matched pattern using regex


I am using gVim on Windows. I have an XML file with content (extracted) like this:

      <ExtendedAttributes />
    </Activity>
    <Activity Id="ded54c70-1ef4-4aeb-852e-3740882c36ff" Name="Activity 1">
      <Performers>
        <Performer>2212646c-2674-4329-9ddc-1f8376e952e1</Performer>
      </Performers>
    </Activity>
    <Activity Id="cf70ec72-4d49-434a-abf3-aa3e8dc000b5" Name="Activity 2">
      <Description>This is a dummy description</Description>
      <Implementation>
        <Task />

I want to add a ID before the name of each activity, i.e.

<Activity Id="ded54c70-1ef4-4aeb-852e-3740882c36ff" Name="Activity 1">

will become

<Activity Id="ded54c70-1ef4-4aeb-852e-3740882c36ff" Name="10 Activity 1">

and

<Activity Id="cf70ec72-4d49-434a-abf3-aa3e8dc000b5" Name="Activity 2">

will become

<Activity Id="cf70ec72-4d49-434a-abf3-aa3e8dc000b5" Name="20 Activity 2">

and so on. I tried \(<Activity Id="[0-9a-f-]*" Name="\)\@<=[A-Za-z ,]\+ which can get the value of the "Name" attribute. But when I try to use the command :let i=0 | g/.... | let i=i+1 mentioned in http://vim.wikia.com/wiki/Making_a_list_of_numbers , I can never make it works. All I can do is to replace the names with the serial number (while I want the [serial number] [name] instead )

Could anyone shed some light?
Thank you very much.

Oliver

[edit]

I tried the followings:

:let @a=1 | %s/\(<Activity Id="[0-9a-f-]*" Name="\)\@<=\([A-Za-z() ,&?;/]\+\)/\=(@a+setreg('a',@a+1))/g

but it replaced the name with number only,

:let @a=1 | %s/\(<Activity Id="[0-9a-f-]*" Name="\)\@<=\([A-Za-z() ,&?;/]\+\)/\=(@a+setreg('a',@a+1)).\2/g

but I get "invalid expression",

:let @a=1 | %s/\(<Activity Id="[0-9a-f-]*" Name="\)\@<=\([A-Za-z() ,&?;/]\+\)/\=(@a+setreg('a',@a+1)).' '.\2/g

but I get "invalid expression",

:let @a=1 | %s/\(<Activity Id="[0-9a-f-]*" Name="\)\@<=\([A-Za-z() ,&?;/]\+\)/\=join((@a+setreg('a',@a+1)),' ',\2)/g

but I get "invalid argument for join()",

:let @a=1 | %s/\(<Activity Id="[0-9a-f-]*" Name="\)\@<=\([A-Za-z() ,&?;/]\+\)/\=(@a+setreg('a',@a+1))+\2/g

but I get "invalid expression".


Solution

  • Assuming your desired ID is the number following Activity multiplied by 10 (that's what i understand from your example), this could be done with:

    :%s/Activity \(\d\+\)/\=submatch(1) * 10 . " " . submatch(0)
    

    Breakdown…