在 Vim 中删除除正则表达式匹配之外的所有内容 [英] Remove everything except regex match in Vim

查看:91
本文介绍了在 Vim 中删除除正则表达式匹配之外的所有内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的具体案例是一个包含大量文本和 IPv4 地址的文本文档.我想删除除 IP 地址之外的所有内容.

My specific case is a text document that contains lots of text and IPv4 addresses. I want to remove everything except for the IP addresses.

我可以使用 :vglobal 来搜索 ([0-9]{1,3}\.){3}[0-9]{1,3} 并删除所有没有 IP 地址的行,但之后我只知道如何搜索整行并选择匹配的文本.有没有更简单的方法.

I can use :vglobal to search for ([0-9]{1,3}\.){3}[0-9]{1,3} and remove all lines without IP addresses, but after that I only know how to search for the whole line and select the matching text. Is there an easier way.

简而言之,我正在寻找一种无需使用外部程序(如 grep)即可执行以下操作的方法:

In short, I'm looking for a way to do the following without using an external program (like grep):

grep --extended-regexp --only-matching --regexp="([0-9]{1,3}\.){3}[0-9]{1,3}"

从 vim 调用 grep 可能需要调整我的正则表达式(例如:删除 \v).使用 vim 的增量搜索表明我的模式是正确的,而且我也不想在 grep 中验证我的正则表达式.

Calling grep from vim may require adapting my regex (ex: removing \v). Using vim's incremental search shows me that I've got the pattern right, and I don't want to verify my regex in grep too.

感谢彼得,这是我现在使用的函数.(C 是我通常在函数中破坏的寄存器.)

Thanks to Peter, here's the function I now use. (C is the register I generally clobber in my functions.)

"" 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:我把它变成了一个接受范围的命令(但默认为整个文件).

I made it a command that accepts ranges (but defaults to whole file).

"" 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()

推荐答案

这个效果可以通过使用 sub-replace-special 替换和 setreg() linewise

This effect can be accomplished by using sub-replace-special substitution and setreg() linewise

:let @a=""
:%s//\=setreg('A', submatch(0), 'l')/g
:%d _
:pu a
:0d _

或全部在一行中:

:let @a=""|%s//\=setreg('A', submatch(0), 'l')/g|%d _|pu a|0d _

概述:使用替换将每个匹配项逐行附加到寄存器a"中,然后将整个缓冲区替换为寄存器a"的内容

Overview: Using a substitution to append each match into register "a" linewise then replace the entire buffer with the contents of register "a"

说明:

  1. 让@a=""清空我们将要附加到的a"寄存器
  2. %s//\=setreg('A', submatch(0), 'l')/g 使用最后一个模式全局替换
  3. \=expr 将用表达式的内容替换模式
  4. submatch(0) 获取刚刚匹配的整个字符串
  5. setreg('A', submatch(0), 'l') 将(注意:大写的a")附加到@a 匹配的字符串,但要逐行
  6. %d _ 删除每一行进入黑洞寄存器(又名@_)
  7. pu a 将@a 的内容放入缓冲区
  8. 0d _ 删除第一行
  1. let @a="" empty the "a" register that we will be appending into
  2. %s//\=setreg('A', submatch(0), 'l')/g substitute globally using the last pattern
  3. the \=expr will replace the pattern with the contents of the expression
  4. submatch(0) get the entire string of what just matched
  5. setreg('A', submatch(0), 'l') append (note: the capital "a") to @a the matched string, but linewise
  6. %d _ delete every line into the black hole register (aka @_)
  7. pu a put the contents of @a into the buffer
  8. 0d _ delete the first line

关注点:

  • 这会破坏您的一个寄存器.这个例子破坏了@a
  • 使用最后一个搜索模式.虽然你可以用你想要的任何模式修改替换命令:%s//\=setreg('A', submatch(0), 'l')/g

更多帮助

:h :s\=
:h :let-@
:h submatch()
:h setreg()
:h :d
:h :p

这篇关于在 Vim 中删除除正则表达式匹配之外的所有内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆