Vim поиск и замена выбранного текста - PullRequest
96 голосов
/ 24 марта 2009

Допустим, у нас есть текст, и я вхожу в визуальный режим и выбираю какой-то текст. Как мне быстро выполнить поиск выделенного текста и заменить его чем-то другим?

Ответы [ 12 ]

116 голосов
/ 24 марта 2009

Попробуйте выполнить следующее или вставьте в .vimrc

vnoremap <C-r> "hy:%s/<C-r>h//gc<left><left><left>

При нажатии ctrl + r в визуальном режиме вам будет предложено ввести текст для замены. Нажмите , введите и затем подтвердите каждое изменение, с которым вы согласны y или отклоните с n .

Эта команда переопределит ваш регистр h, чтобы вы могли выбрать другой (изменив h в приведенной выше команде на другую строчную букву), который вы не используете.

31 голосов
/ 10 апреля 2013

Это быстрый и простой поиск сопоставления для визуально выделенного текста (без перезаписи регистра h) и без использования регистра + зависимого от терминала:

" search for visually hightlighted text
vnoremap <c-f> y<ESC>/<c-r>"<CR>   

Если вам не нравится ctrl-f, измените его по своему вкусу

После выделения текста вы всегда можете сделать замену s, просто набрав:

%s//<your-replacement-string>

... потому что при пустом поиске по команде s используется последняя найденная строка.

22 голосов
/ 30 мая 2011

Принятый ответ прекрасно работает, если у вас нет специальных символов в вашем визуальном отборе. Я взломал два скрипта ( Джереми Кантрелл опубликован здесь и Питер Оддинг ), чтобы создать команду, которая позволит вам визуально выбрать строку, которую вы хотите найти, даже если в нем есть специальные символы регулярного выражения.

" Escape special characters in a string for exact matching.
" This is useful to copying strings from the file to the search tool
" Based on this - http://peterodding.com/code/vim/profile/autoload/xolox/escape.vim
function! EscapeString (string)
  let string=a:string
  " Escape regex characters
  let string = escape(string, '^$.*\/~[]')
  " Escape the line endings
  let string = substitute(string, '\n', '\\n', 'g')
  return string
endfunction

" Get the current visual block for search and replaces
" This function passed the visual block through a string escape function
" Based on this - /617096/vim-poisk-i-zamena-vybrannogo-teksta#617118
function! GetVisual() range
  " Save the current register and clipboard
  let reg_save = getreg('"')
  let regtype_save = getregtype('"')
  let cb_save = &clipboard
  set clipboard&

  " Put the current visual selection in the " register
  normal! ""gvy
  let selection = getreg('"')

  " Put the saved registers and clipboards back
  call setreg('"', reg_save, regtype_save)
  let &clipboard = cb_save

  "Escape any special characters in the selection
  let escaped_selection = EscapeString(selection)

  return escaped_selection
endfunction

" Start the find and replace command across the entire file
vmap <leader>z <Esc>:%s/<c-r>=GetVisual()<cr>/

Я включил это в мой vimrc , если это кому-нибудь более полезно.

17 голосов
/ 12 июля 2013

Этот вариант также работает (по крайней мере, для выборок в одной строке / выборок, которые не содержат специальных символов)

  • выделение текста в визуальном режиме
  • восстановить текст с помощью y
  • :s/<C-r>0/

0 - регистр янки.

Как уже упоминали другие люди, есть более быстрые способы сделать это, но если вы только начали изучать Vim (как я), это один из «общих» способов.

// edit: я только что понял, что подход 'register' потерпит неудачу, если в выделении будут такие символы, как символы табуляции или перехода на новую строку или символы / (мне пришлось бы каким-то образом обрабатывать эти символы вручную :s команда для работы):

enter image description here

8 голосов
/ 01 декабря 2011

С http://vim.wikia.com/wiki/Search_and_replace_in_a_visual_selection:

Когда текст выделен визуально, нажмите: для ввода команды. Командная строка автоматически введет диапазон:

:'<,'>

Вы можете ввести команду, например s / red / green / g, чтобы заменить каждый красный цвет на зеленый во всех строках последнего визуального выбора. Команда будет выглядеть как:

:'<,'>s/red/green/g

Чтобы повторить команду Ex для ранее выбранного блока, используйте: history. То есть нажмите: затем, затем отредактируйте предыдущую команду.

6 голосов
/ 08 мая 2011

Николай Голубев, Спасибо за чаевые! Далее используется регистр «+», который (в зависимости от вашего терминала) уже содержит выделенный текст, за исключением использования регистра «h».

vnoremap <C-r> <Esc>:%s/<C-r>+//gc<left><left><left>
5 голосов
/ 26 марта 2017

В Vim 7.4 вы можете использовать движение gn, которое выбирает области текста, соответствующие текущему шаблону поиска.

После использования cgn для изменения текста в текущем выбранном совпадении (или dgn для удаления) в обычном режиме вы можете использовать ., чтобы повторить команду и перейти к следующему совпадению.

Есть эпизод Vimcast , показывающий эту функцию.

4 голосов
/ 24 марта 2009

У меня есть это в моем vimrc:

function! GetVisual() range
    let reg_save = getreg('"')
    let regtype_save = getregtype('"')
    let cb_save = &clipboard
    set clipboard&
    normal! ""gvy
    let selection = getreg('"')
    call setreg('"', reg_save, regtype_save)
    let &clipboard = cb_save
    return selection
endfunction

vmap <leader>z :%s/<c-r>=GetVisual()<cr>/

Это захватит визуальный выбор и начнет с ним команду подстановки.

РЕДАКТИРОВАТЬ: я должен отметить, что это не работает с многострочным визуальным выбором. Хотя у GetVisual () нет проблем с его возвратом, я не уверен, как правильно поместить его в командную строку. Если у кого-нибудь есть какие-либо советы о том, как я могу это сделать, пожалуйста, прокомментируйте.

1 голос
/ 24 марта 2009

Я не думаю, что вы можете сделать это из коробки. Но многим людям нравится эта функция, так что есть множество макросов и тому подобное (я добавил это сам). Здесь - это то, что вы можете добавить, например; просто нажмите *, чтобы найти следующее совпадение в визуально выделенном тексте.

0 голосов
/ 26 июля 2017

Пример 1. Цитировать выделение со звездами, держать курсор в начале выделения.

:%s,\%#\%V\_.*\%V/,**&**,c 

Пример 2. Передача выделенного текста с base64:

:%s!\%#\%V\_.*\%V!\=system("base64 -w 0",@")!c

Объяснение LHS:

\%# matches cursor 
\%V matches inside the selection only
\_. matches any character.
\_.* matches beginning to end of selection.

Объяснение RHS:

\=expr()  Replace match with result of expr() for each substitution.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...