统计一段字符串的字符数
Count characters of a section of a string
我有这个 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")
它描述了不同的 URL,我正在尝试计算 主机名 的字符数,是否是真实名称 (http://hostname.com/....) or an IP(http://000.000.000.000/..)。但是,如果它是一个实际名称,那么我只想要 www 之间的 nchar。和.com。如果它是一个 IP,那么它的所有数字和 "in between" 点。
上述示例数据的预期结果:
exp_outcome
1 8
2 13
3 15
4 4
5 7
我尝试用 strsplit
做点什么,但什么也做不了。
操作方法如下(假设您的 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
根本没有意义。
另一种可能更直接的方式,使用不同的正则表达式:
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]+)?
: 寻找“.”后跟一个或多个小写字母,零次或一次(因此再次可选)
/+.+$
:查找“/”后跟任何内容,一次或多次直到字符串结尾
注意:
sub("^http://(www\.)?(([a-z]+)|([0-9.]+))(\.[a-z]+)?/+.+$", "\2", x$df)
# [1] "bursesvp" "46.165.216.78" "chalcedonyhotel" "bmbt" "voeazul"
经过 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
我有这个 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")
它描述了不同的 URL,我正在尝试计算 主机名 的字符数,是否是真实名称 (http://hostname.com/....) or an IP(http://000.000.000.000/..)。但是,如果它是一个实际名称,那么我只想要 www 之间的 nchar。和.com。如果它是一个 IP,那么它的所有数字和 "in between" 点。
上述示例数据的预期结果:
exp_outcome
1 8
2 13
3 15
4 4
5 7
我尝试用 strsplit
做点什么,但什么也做不了。
操作方法如下(假设您的 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
根本没有意义。
另一种可能更直接的方式,使用不同的正则表达式:
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]+)?
: 寻找“.”后跟一个或多个小写字母,零次或一次(因此再次可选)/+.+$
:查找“/”后跟任何内容,一次或多次直到字符串结尾
注意:
sub("^http://(www\.)?(([a-z]+)|([0-9.]+))(\.[a-z]+)?/+.+$", "\2", x$df)
# [1] "bursesvp" "46.165.216.78" "chalcedonyhotel" "bmbt" "voeazul"
经过 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