Вы можете сделать это в vim, используя словарь:
:%s/quick\|lazy/\={'quick':'slow','lazy':'energetic'}[submatch(0)]/g
Это изменит следующий текст:
быстрый бурый лис бежал быстрый рядом с ленивым ручьем.
в
медленный бурый лис бежал медленный только рядом с энергичным ручьем.
Чтобы увидеть, как это работает, см. :help sub-replace-expression
и :help Dictionary
. Короче,
\=
позволяет подставлять в результат выражения vim.
{'quick':'slow', 'lazy':'energetic'}
- это словарь vim (например, хеш в perl или ruby или объект в javascript), который использует []
для поиска.
submatch(0)
соответствует строке
Это может пригодиться при рефакторинге кода - скажем, вы хотите обменять имена переменных на foo
, bar
и baz
, меняющие
foo
& rarr; bar
bar
& rarr; baz
baz
& rarr; foo
Использовать последовательность команд %s///
было бы непросто, если только вы не использовали временные имена переменных - но вы должны были убедиться, что они не затрагивают ничего другого. Вместо этого вы можете использовать словарь, чтобы сделать это за один проход:
:%s/\<\%(foo\|bar\|baz\)\>/\={'foo':'bar','bar':'baz','baz':'foo'}[submatch(0)]/g
Что меняет этот код
int foo = 0;
float bar = pow(2.0, (float) foo);
char baz[256] = {};
sprintf(baz,"2^%d = %f\n", foo, bar);
в
int bar = 0;
float baz = pow(2.0, (float) bar);
char foo[256] = {};
sprintf(foo,"2^%d = %f\n", bar, baz);
Если вы часто этим занимаетесь, вы можете добавить к своему ~/.vimrc
следующее:
" Refactor the given lines using a dictionary
" replacing all occurences of each key in the dictionary with its value
function! Refactor(dict) range
execute a:firstline . ',' . a:lastline . 's/\C\<\%(' . join(keys(a:dict),'\|'). '\)\>/\='.string(a:dict).'[submatch(0)]/ge'
endfunction
command! -range=% -nargs=1 Refactor :<line1>,<line2>call Refactor(<args>)
Это позволяет вам использовать команду :Refactor {'frog':'duck', 'duck':'frog'}
, и немного
менее повторяющийся, чем создание регулярного выражения для dict вручную.