gVim вставьте серийный номер перед каждым сопоставленным шаблоном с помощью регулярных выражений

Я использую gVim на Windows. У меня есть XML-файл с содержимым (извлечено), как это:

      <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 />

Я хочу добавить идентификатор перед названием каждой деятельности, т.е.

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

станет

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

а также

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

станет

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

и так далее. Я старался \(<Activity Id="[0-9a-f-]*" Name="\)\@<=[A-Za-z ,]\+ который может получить значение атрибута "Имя". Но когда я пытаюсь использовать команду :let i=0 | g/.... | let i=i+1 упомянутый в http://vim.wikia.com/wiki/Making_a_list_of_numbers, я никогда не смогу заставить его работать. Все, что я могу сделать, это заменить имена на серийный номер (вместо этого я хочу использовать [серийный номер] [имя])

Может ли кто-нибудь пролить свет?
Большое спасибо.

Оливер

[редактировать]

Я попробовал следующее:

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

но он заменил имя только номером,

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

но я получаю "недопустимое выражение",

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

но я получаю "недопустимое выражение",

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

но я получаю "недопустимый аргумент для join()",

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

но я получаю "недопустимое выражение".

3 ответа

Решение

Предполагая, что ваш желаемый идентификатор является число после Activity умножить на 10 (это то, что я понимаю из вашего примера), это можно сделать с помощью:

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

Сломать…

  • Выполните подстановку в каждой строке:

    :%s/...
    
  • Ищи Activity, за которым следует пробел, за которым следуют одно или несколько чисел, запишите числа:

    .../Activity \(\d\+\)/...
    
  • Используйте захваченное число и все совпадение в "выражении подстановки":

    .../\=submatch(1)*10 . " " . submatch(0)
    

    где мы объединяем захваченное число на 10, пробел и все совпадение.

    Увидеть :help sub-replace,

Я наконец-то нашел способ выполнить задачу в 2 этапа:

1) Вставьте статическую строку, которая вряд ли появится в содержимом (например, ##%%##%%) командой:

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

2) Заменить статическую строку числовой последовательностью:

:let @a=1 | %s/##%%##%%/\=(@a+setreg('a',@a+1))/g

Это действительно не идеальное решение. Любое решение только за 1 шаг приветствуется. Большое спасибо.

Этот изменяется только в Деятельности, которая находится в конце строки. Сначала попробуем поискать отдельно

/Name="\zs[^"]*\ze"

Тогда спросите нашу любимую Вим

let @a=10 | %s//\=(@a+setreg('a', @a+10)) . " " . submatch(0)
Другие вопросы по тегам