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)