计算字符串

时间:2016-01-13 15:42:42

标签: r strsplit

我有这个df:

dput(df)
structure(list(URLs = c("http://bursesvp.ro//portal/user/_/Banco_Votorantim_Cartoes/0-7f2f5cb67f1-22918b.html", 
"http://46.165.216.78/.CartoesVotorantim/Usuarios/Cadastro/BV6102891782/", 
"http://www.chalcedonyhotel.com/images/promoc/premiado.tam.fidelidade/", 
"http://bmbt.ro/portal/a3/_Votorantim_/VotorantimCartoes2016/0-7f2f5cb67f1-22928b.html", 
"http://voeazul.nl/azul/")), .Names = "URLs", row.names = c(NA, 
-5L), class = "data.frame")

它描述了不同的网址,我正在尝试计算主机名的字符数,无论是实际名称(http://hostname.com/...。)还是IP({{3 }})。但是,如果它是一个实际名称,那么我只想要www之间的nchar。和.com。如果它是IP,那么它的所有数字和“中间”点。

上述样本数据的预期结果:

exp_outcome
1           8
2          13
3          15
4           4
5           7

我尝试用strsplit做某事,但无法到达任何地方。

3 个答案:

答案 0 :(得分:8)

另一种,也许更直接的方式使用不同的正则表达式:

nchar(sub("^http://(www\\.)?(([a-z]+)|([0-9.]+))(\\.[a-z]+)?/+.+$", "\\2", x$df))
#[1]  8 13 15  4  7

<强>解释

  • ^http://:在字符串
  • 开头后查找“http://”
  • (www\\.)?:查找“www。”,零次或一次(所以这是可选的)
  • (([a-z]+)|([0-9.]+)):将捕获的模式:小写字母一个或多个时间或数字和点
  • (\\.[a-z]+)?:寻找“。”后跟一个或多个小写字母,零或一次(所以再次可选)
  • /+.+$:查找“/”后跟任何内容,一次或多次直到字符串结尾

NB:

sub("^http://(www\\.)?(([a-z]+)|([0-9.]+))(\\.[a-z]+)?/+.+$", "\\2", x$df)
# [1] "bursesvp"        "46.165.216.78"   "chalcedonyhotel" "bmbt"            "voeazul"  

答案 1 :(得分:6)

以下是如何操作(假设data.frame被称为x):

domains = sub('^(http://)([^/]+)(.*)$', '\\2', x$df)
# This will fail for IP addresses …
hostname = sub('^(www\\.)?([^.]+)(\\..+)?$', '\\2', domains)
# … which we treat separately here:
is_ip = grepl('^(\\d{1,3}\\.){3}\\d{1,3}$', domains)
hostname[is_ip] = domains[is_ip]

exp_outcome$domain_length = nchar(hostname)

在旁注中,我将原始data.frame转换为字符串 - 对于URL使用factor毫无意义。

答案 2 :(得分:1)

经过5个月的URL处理后,我发现以下软件包让生活变得更轻松(其他答案提供的正则表达式确实很顺利),

library(urltools)
library(iptools)

df$Hostname <- domain(df$URLs)
#However, TLDs and 'www' need to go so I used suffix_extract()$domain from `iptools` 
df$Hostname <- ifelse(is.na(suffix_extract(df$Hostname)$domain), df$Hostname, 
                                          suffix_extract(df$Hostname)$domain)

#which gives:
#   URLs                                                          Hostname
#1  http://bursesvp.ro//portal/user/_/...                         bursesvp
#2  http://46.165.216.78/.CartoesVotorantim/Usuarios/...          46.165.216.78
#3 http://www.chalcedonyhotel.com/images/promoc/                  chalcedonyhotel
#4 http://bmbt.ro/portal/a3/_Votorantim_/...                      bmbt
#5 http://voeazul.nl/azul/                                        voeazul

#then simply,

nchar(df$Hostname)
#[1]  8 13 15  4  7