【发布时间】:2010-12-21 20:46:17
【问题描述】:
我的具体案例是一个包含大量文本和 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}"
从 vim 调用 grep 可能需要调整我的正则表达式(例如:删除 \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()
【问题讨论】:
-
你可以停止破坏,因为你正在使用一个函数。这是通过在函数的开头使用
let old = @c保存@c 寄存器并在末尾使用let @c = old恢复它来完成的。