我需要一个在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
它正在做以下事情:
let g:gotDomains={}
创建一个空字典,我们将保存所有的域 %g/^/{command}
每行执行{command}
let curDomain=matchstr(...)
获取域名
getline('.')
\v
让我省略在正则表达式写很多反斜杠(非常神奇) ^
从字符串的开始 \zs
从这里开始匹配(省略捕获\zs
之前的所有内容) if !has_key(g:gotDomains, curDomain)
如果域之前没有发生过。
let g:gotDomains[curDomain]=1
然后将其添加到已知域的列表(我们不需要在这里1
,我只使用字典为更快的访问)。 delete _
否则将行删除到黑洞寄存器(这意味着,不要将其内容保存在任何寄存器中)。 尝试这个:
%! sort | uniq