Моим конкретным случаем является текстовый документ, который содержит много текстовых и 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 - это регистр, который я обычно clobber в моих функциях.)
"" 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 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()