Для тех, кто ищет чистое решение Vim, вот более каноническое и общее решение, чем в ответе @ sidyll, которое не требует :perldo
или :global
, а также будет работать с несколькими совпадениями в строке (добавляяg
флаг :substitute
):
со встроенной заменой
В Vim вы можете использовать :help sub-replace-expression
для замены текста произвольными выражениями.К сожалению, приращение переменной - это оператор в Vim, а не выражение.Либо приходится прибегать к уловкам, таким как использование длины List в качестве счетчика (add()
можно использовать в выражении):
:let c = [] | %substitute/XYZ/\=len(add(c, 0))/
Или вам нужно определить отдельную функцию (один раз):
function! Increment()
let g:i += 1
return g:i
endfunction
let g:i = 0 | %substitute/XYZ/\=Increment()/
С плагином
Синтаксис выражения немного странный (но если вы в Perl, вы привыкли к гораздо худшему :-).Кроме того, явная отдельная инициализация счетчика (и функции) является громоздкой.Мой плагин PatternsOnText улучшает встроенную команду :substitute
в нескольких вариантах.Среди них :SubstituteExecute
, который извлекает выгоду из предопределенного объекта контекста:
:%SubstituteExecute /XYZ/ let v:val.n += 1 | return v:val.n
Перенумерация является настолько частой задачей, что плагин даже имеет специальную команду для нее:
:Renumber /XYZ/
Предостережения
- Структурированный, но гибкий синтаксис, такой как HTML или JSON, плохо подходит для анализа регулярных выражений, если только вы не уверены, что используемое подмножество разрешенного синтаксиса является очень регулярным (например, потому что вы знаете источник вводаи / или прошли ввод через симпатичный принтер).Предпочитайте специализированные инструменты обычным (т. Е. Используйте
xmlstarlet
для XML и jq
для JSON вместо grep
и sed
).