我有一个我想要解析和规范化的网址列表。
我希望能够将每个地址拆分为多个部分,以便我可以将“www.google.com/test/index.asp”和“google.com/somethingelse”标识为来自同一网站。
答案 0 :(得分:12)
由于parse_url()
无论如何都使用正则表达式,我们也可以重新发明轮子并创建一个正则表达式替换,以便建立一个甜蜜而花哨的gsub
调用。
我们来看看。 URL由一个协议组成,一个“netloc”,可能包括用户名,密码,主机名和端口组件,以及我们乐意剥离的余数。我们首先假设没有用户名,密码和端口。
^(?:(?:[[:alpha:]+.-]+)://)?
将匹配协议标头(从parse_url()
复制),如果我们找到它,我们就会剥离它www.
前缀已被删除,但未被捕获:(?:www\\.)?
([^/]+)
.*$
现在我们将上面的正则表达式拼接在一起,主机名的提取变为:
PROTOCOL_REGEX <- "^(?:(?:[[:alpha:]+.-]+)://)?"
PREFIX_REGEX <- "(?:www\\.)?"
HOSTNAME_REGEX <- "([^/]+)"
REST_REGEX <- ".*$"
URL_REGEX <- paste0(PROTOCOL_REGEX, PREFIX_REGEX, HOSTNAME_REGEX, REST_REGEX)
domain.name <- function(urls) gsub(URL_REGEX, "\\1", urls)
更改主机名正则表达式以包括(但不捕获)端口:
HOSTNAME_REGEX <- "([^:/]+)(?::[0-9]+)?"
依此类推,直到我们最终到达RFC-compliant regular expression for parsing URLs。但是,对于家庭使用,上述内容应该足够了:
> domain.name(c("test.server.com/test", "www.google.com/test/index.asp",
"http://test.com/?ex"))
[1] "test.server.com" "google.com" "test.com"
答案 1 :(得分:10)
您可以使用R package httr
的功能 parse_url(url)
>parse_url("http://google.com/")
您可以在此处获取更多详细信息: http://cran.r-project.org/web/packages/httr/httr.pdf
答案 2 :(得分:5)
现在还有urltools
个软件包,无限更快:
urltools::url_parse(c("www.google.com/test/index.asp",
"google.com/somethingelse"))
## scheme domain port path parameter fragment
## 1 www.google.com test/index.asp
## 2 google.com somethingelse
答案 3 :(得分:4)
我放弃了一个包并使用正则表达式。
在Dason的机器人攻击后重新制定了EDIT ......
x <- c("talkstats.com", "www.google.com/test/index.asp",
"google.com/somethingelse", "www.stackoverflow.com",
"http://www.bing.com/search?q=google.com&go=&qs=n&form=QBLH&pq=google.com&sc=8-1??0&sp=-1&sk=")
parser <- function(x) gsub("www\\.", "", sapply(strsplit(gsub("http://", "", x), "/"), "[[", 1))
parser(x)
lst <- lapply(unique(parser(x)), function(var) x[parser(x) %in% var])
names(lst) <- unique(parser(x))
lst
## $talkstats.com
## [1] "talkstats.com"
##
## $google.com
## [1] "www.google.com/test/index.asp" "google.com/somethingelse"
##
## $stackoverflow.com
## [1] "www.stackoverflow.com"
##
## $bing.com
## [1] "http://www.bing.com/search?q=google.com&go=&qs=n&form=QBLH&pq=google.com&sc=8-1??0&sp=-1&sk="
这可能需要根据数据结构进行扩展。
答案 4 :(得分:3)
在R_Newbie的答案的基础上,这是一个函数,它将从(矢量)URL中提取服务器名称,剥离www.
前缀(如果存在),并优雅地忽略丢失的协议前缀。
domain.name <- function(urls) {
require(httr)
require(plyr)
paths <- laply(urls, function(u) with(parse_url(u),
paste0(hostname, "/", path)))
gsub("^/?(?:www\\.)?([^/]+).*$", "\\1", paths)
}
parse_url
函数用于提取path
参数,该参数由gsub
进一步处理。正则表达式的/?
和(?:www\\.)?
部分将匹配可选的前导斜杠,后跟可选的www.
,[^/]+
匹配之后但在第一个斜杠之前的所有内容 - - 这被捕获并有效地用于gsub
电话的替换文本。
> domain.name(c("test.server.com/test", "www.google.com/test/index.asp",
"http://test.com/?ex"))
[1] "test.server.com" "google.com" "test.com"
答案 5 :(得分:2)
如果你喜欢tldextract,一个选项就是使用appengine上的版本
require(RJSONIO)
test <- c("test.server.com/test", "www.google.com/test/index.asp", "http://test.com/?ex")
lapply(paste0("http://tldextract.appspot.com/api/extract?url=", test), fromJSON)
[[1]]
domain subdomain tld
"server" "test" "com"
[[2]]
domain subdomain tld
"google" "www" "com"
[[3]]
domain subdomain tld
"test" "" "com"