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

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

我在一个.txt文件中有一个超过600万个URL的列表(在gVim中打开进行编辑)。

这些url的格式如下:

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编写的正则expression式,它将从列表中删除所有重复的DOMAIN(它是相应的URL),留下它find的第一个实例。

因此,需要上面列出的示例列表,最终结果应该如下所示:

 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中使用正则expression式:

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

如果你想用正则表达式来做,你可以尝试调整以下内容: %s!\v%(^http://%(www\.)?(%([^./]+\.)+[^./]+)%(/.*)?$\_.{-})@<=^http://%(www\.)?\1%(/.*)?\n!!g ,但是在六十亿的网址上会慢,不知道原因。 这是一个更好的方法:

 :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. \zs从这里开始匹配(省略捕获\zs之前的所有内容)
  4. if !has_key(g:gotDomains, curDomain)如果域之前没有发生过。

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

尝试这个:

 %! sort | uniq