Мой конкретный случай - это текстовый документ, который содержит много текста и адресов IPv4. Я хочу удалить все, кроме IP-адресов.
Я могу использовать :vglobal
для поиска ([0-9]{1,3}\.){3}[0-9]{1,3}
и удаления всех строк без IP-адресов, но после этого я знаю только, как искать всю строку и выбирать соответствующий текст. Есть ли более простой способ.
Короче говоря, я ищу способ сделать следующее без использования внешней программы (например, grep):
grep --extended-regexp --only-matching --regexp="([0-9]{1,3}\.){3}[0-9]{1,3}"
Для вызова grep из vim может потребоваться адаптация моего регулярного выражения (например, удаление \ v). Использование инкрементального поиска в vim показывает, что у меня есть правильный шаблон, и я не хочу проверять свое регулярное выражение в grep.
Редактировать: Благодаря Питеру, вот функция, которую я сейчас использую. (C - это регистр, который я обычно использую в своих функциях.)
"" Remove all text except what matches the current search result
"" The opposite of :%s///g (which clears all instances of the current search).
function! ClearAllButMatches()
let old = @c
let @c=""
%s//\=setreg('C', submatch(0), 'l')/g
%d _
put c
0d _
let @c = old
endfunction
Edit2: Я сделал это командой, которая принимает диапазоны (но по умолчанию весь файл).
"" Remove all text except what matches the current search result. Will put each
"" match on its own line. This is the opposite of :%s///g (which clears all
"" instances of the current search).
function! s:ClearAllButMatches() range
let is_whole_file = a:firstline == 1 && a:lastline == line('$')
let old_c = @c
let @c=""
exec a:firstline .','. a:lastline .'sub//\=setreg("C", submatch(0), "l")/g'
exec a:firstline .','. a:lastline .'delete _'
put! c
"" I actually want the above to replace the whole selection with c, but I'll
"" settle for removing the blank line that's left when deleting the file
"" contents.
if is_whole_file
$delete _
endif
let @c = old_c
endfunction
command! -range=% ClearAllButMatches <line1>,<line2>call s:ClearAllButMatches()