gVim中的正则表达式从列表中删除重复域

时间:2010-10-23 02:18:44

标签: windows regex vim

我需要编写一个在gVim中使用的正则表达式,它将从URL列表中删除重复的域(gVim可以在这里下载:http://www.vim.org/download.php

我在.txt文件中有一个超过6,000,000个网址的列表(在gVim中打开以进行编辑)。

网址采用以下格式:

http://www.example.com/some-url.php
http://example2.com/another_url.html
http://example3.com/
http://www.example4.com/anotherURL.htm
http://www.example.com/some-url2.htm
http://example.com/some-url3.html
http://www.example2.com/somethingelse.php
http://example5.com

换句话说,URL没有特定的格式。有些人有WWW,有些没有,他们都有不同的格式。

我需要为gVim编写的正则表达式,它将从列表中删除所有重复的DOMAIN(以及它的相应URL),留下它找到的第一个实例。

所以它将采用上面发布的示例列表,最终结果应如下所示:

http://www.example.com/some-url.php
http://example2.com/another_url.html
http://example3.com/
http://www.example4.com/anotherURL.htm
http://example5.com

以下是两个很好的网站,解释了如何在gVim中使用正则表达式:

http://supportweb.cs.bham.ac.uk/documentation/tutorials/docsystem/build/tutorials/gvim/gvim.html#Vi-Regular-Expressions

http://www.softpanorama.org/Editors/Vimorama/vim_regular_expressions.shtml

2 个答案:

答案 0 :(得分:4)

如果您想使用正则表达式执行此操作,可以尝试调整以下内容:%s!\v%(^http://%(www\.)?(%([^./]+\.)+[^./]+)%(/.*)?$\_.{-})@<=^http://%(www\.)?\1%(/.*)?\n!!g,但在60亿个网址上它将非常缓慢且不起作用原因不明。这是一个更好的方法:

:let g:gotDomains={}
:%g/^/let curDomain=matchstr(getline('.'), '\v^http://%(www\.)?\zs[^/]+') | if !has_key(g:gotDomains, curDomain) | let g:gotDomains[curDomain]=1 | else | delete _ | endif

它正在执行以下操作:

  1. let g:gotDomains={}创建一个空字典,我们将保留所有域
  2. %g/^/{command}在每一行执行{command}
  3. let curDomain=matchstr(...)获取域名

      来自当前行的
    1. getline('.')
    2. \v允许我省略在正则表达式中写出大量反斜杠(非常神奇)
    3. ^从字符串
    4. 开始
    5. \zs从这里开始匹配(省略捕捉\zs之前的所有内容)
  4. if !has_key(g:gotDomains, curDomain)如果以前没有发生域名。

  5. let g:gotDomains[curDomain]=1然后将其添加到已知域列表中(我们这里不需要1,我只使用字典来加快访问速度。)
  6. delete _否则删除黑洞寄存器的行(这意味着,不要将其内容保存在任何寄存器中)。

答案 1 :(得分:-1)

试试这个:

%! sort | uniq