从URL的字符向量开始。目标是最终只使用公司名称,这意味着下面的示例中只有"test"
,"example"
和"sample"
的列。
urls <- c("http://grand.test.com/", "https://example.com/",
"http://.big.time.sample.com/")
删除".com"
及其后跟随的内容并保留第一部分:
urls <- sapply(strsplit(urls, split="(?<=.)(?=\\.com)", perl=T), "[", 1)
urls
# [1] "http://grand.test" "https://example" "http://.big.time.sample"
我的下一步是通过链接http://
来删除https://
和gsub()
部分:
urls <- gsub("^http://", "", gsub("^https://", "", urls))
urls
# [1] "grand.test" "example" ".big.time.sample"
但这是我需要帮助的地方。如何在第一个和第三个网址字符串中处理公司名称之前的多个句点(点)?例如,下面的调用返回第二个字符串的NA,因为"example"
字符串没有剩余句点。或者,如果我只保留第一部分,我就会丢失公司名称。
urls <- sapply(strsplit(urls, split = "\\."), "[", 2)
urls
# [1] "test" NA "big"
urls <- sapply(strsplit(urls, split = "\\."), "[", 1)
urls
# [1] "grand" "example" ""
也许ifelse()
来电会计算剩余时段的数量,如果有多个时段,则仅使用strsplit?另请注意,公司名称前可能有两个或更多个期间。我不知道如何做外观,这可能解决我的问题。但这并没有
strsplit(urls, split="(?=\\.)", perl=T)
感谢您提出任何建议。
答案 0 :(得分:3)
我认为应该更简单,但这有效:
sub('.*[.]','',sub('https?:[/]+[.]?(.*)[.]com[/]','\\1',urls))
[1] "test" "example" "sample"
你在哪里“网址”是你的网址。
答案 1 :(得分:3)
我认为有一种方法可以在&#39; .com`之前提取这个词,但也许会给出一个想法
sub(".com", "", regmatches(urls, gregexpr("(\\w+).com", urls)))
答案 2 :(得分:3)
这种方法可能比其他方法更容易理解和概括:
pat = "(.*?)(\\w+)(\\.com.*)"
gsub(pat, "\\2", urls)
它的工作原理是将每个字符串分成三个捕获组,这三个捕获组一起匹配整个字符串,然后在仅捕获组(2)
中替换为您想要的那个。
pat = "(.*?)(\\w+)(\\.com.*)"
# ^ ^ ^
# | | |
# (1) (2) (3)
修改(添加?
修饰符的说明):
请注意,捕获组(1)
需要包含“ungreedy”或“minimal”量词?
(also sometimes called "lazy" or "reluctant")。它基本上告诉正则表达式引擎匹配尽可能多的字符...而不用掉任何可能成为以下捕获组(2)
的一部分的字符。
没有尾随?
,重复量词默认为贪心;在这种情况下,一个贪婪的捕获组(.*)
,因为它匹配任意数量的任何类型的字符,将“吃掉”字符串中的所有字符,而对于其他两个捕获组则根本不留下任何字符 - 不是我们想要的行为!
答案 3 :(得分:2)
使用strsplit
也值得一试:
sapply(strsplit(urls,"/|\\."),function(x) tail(x,2)[1])
#[1] "test" "example" "sample"
答案 4 :(得分:2)
这是一个很好的例子。有用的答案和一些解释很快就产生了。
回答我自己的问题并没有描述我在做什么。我想感谢贡献者,回馈一些可以帮助其他人看看这个问题,并解释为什么我选择了一个答案。评论似乎不对,也不够长。
下面将我的每个答案与我的(谦虚,并且很乐意纠正)解释,其中几个包含来自答复者的解释。仔细阅读答案教会了我很多,并帮助我选择了一个首选答案。其他人使用非基本R函数,一个创建的函数,可能很好但不是很容易获得。我喜欢第二个答案,因为它只使用了子功能,但我将桂冠花圈送到了第五个,因为它优雅地使用了我非常高兴学习的两种技术。谢谢大家。
ANS 1
sub(".com", "", regmatches(urls, gregexpr("(\\w+).com", urls)))
gregexpr
在“w+”
之前使用特殊字词“.com”
找到任何一个或多个单词,并返回一个包含length和usebytes的列表
regmatches
获取gregexpr
找到的内容并返回已识别的字符串
sub
从每个字符串中删除第一个“.com”[我不知道为什么gsub不起作用,但是当你只想要第一个实例时,全局子可能存在风险]
ANS 2
sub('.*[.]','', sub('https?:[/]+[.]?(.*)[.]com[/]','\\1',urls))
内部子句通过问号特殊字符?处理“http:”和“https:”,这允许“s”是可选的
内部子函数然后处理一个或多个“/”,其中一个字符类只包含一个正斜杠但由“+”
扩展,即在http://
内部子正则表达式向右读取的下一部分包括任意数量的字符作为“[.]?
接下来,“com”之前的句号放在括号中而不是转义它
然后“com”接着是正斜杠[我不确定我理解那部分]
“’\\1’
仅保留子函数提取的第一部分
所有上述内容都会返回:
[1] "grand.test" "example" "big.time.sample"
最左边的子函数获取内部子函数的结果,并删除括号内的“.*”
之前的所有字符
ANS 3
sapply(strsplit(urls, "/|\\."), function(x) tail(x,2)[1])
首先,strsplit
使用垂直管道将每个字符串分隔正斜杠或句点产生一个列表
[[1]]
[1] "http:" "" "grand" "test" "com"
[[2]]
[1] "https:" "" "example" "com"
[[3]]
[1] "http:" "" "" "big" "time" "sample" "com"
接下来,一个匿名函数使用tail
函数找到每个字符串中的最后两个元素,并选择第一个元素,从而整齐地消除每个“.com”
使用sapply函数包装这两个步骤将匿名函数的操作向量化为所有三个字符串
ANS 4
library(stringr)
word(basename(urls), start = -2, sep = "\\.")
basename
函数返回
[1] "grand.test.com" "example.com" ".big.time.sample.com"
从帮助到basename()
我们了解到“basename删除了所有路径,包括最后一个路径分隔符(如果有的话)”这整齐地删除了http://和https://元素。
然后,word()
函数使用负运算符(start = -2)从末尾获取第二个“单词”,假设分隔符为。 (期间)(sep =“\。”)。
ANS 5
pat = "(.*?)(\\w+)(\\.com.*)"
gsub(pat, "\\2", urls)
分配给对象“pat”的正则表达式将每个字符串分成三个捕获组,这些捕获组一起匹配整个字符串
使用gsub
函数,搜索“pat”字符串,它将仅替换为捕获组(2),即所需部分。
请注意两种技术:使用表达式创建对象,然后在正则表达式中使用它。此方法有助于保持代码更清晰,更易于阅读 - 如gsub调用行所示。其次,请注意捕获组的使用,捕获组是括在括号中的正则表达式的组成部分。它们可以在以后使用,就像本例中的“'\ 2'”
一样pat = "(.*?)(\\w+)(\\.com.*)"
# ^ ^ ^
# | | |
# (1) (2) (3)
ANS 6
regcapturedmatches(urls, regexpr("([^.\\/]+)\\.com", urls, perl=T))
这可能是一个很好的解决方案,但它依赖的函数regcapturematches
不在基础R或其他包中,例如qdap
或stringi
或{{1} }
先生。 Flick提出了一个很好的观点,“如果你只需要一个简单的向量作为返回值,你就可以取消列出()结果。”
他解释说“模式的想法是在”.com“之前抓住所有不是点或”/“的东西。”这是括号中的表达式,+符号表示它可以是多。
Perl = T似乎是所有正则表达式的好参数
答案 5 :(得分:1)
您可以使用stringr::word()
以及basename()
。
basename()
非常方便。
> library(stringr)
> word(basename(urls), start = -2, sep = "\\.")
# [1] "test" "example" "sample"
basename(urls)
给出了
[1] "grand.test.com" "example.com" ".big.time.sample.com"
然后,在word()
函数中,我们从结尾(start = -2
)获取第二个单词,假设分隔符为.
(sep = "\\."
)。
答案 6 :(得分:1)
因为你从来没有足够的正则表达式选项,所以这里使用regcapturedmatches.R函数
regcapturedmatches(urls, regexpr("([^.\\/]+)\\.com", urls, perl=T))
如果您只需要一个简单的向量作为返回值,则可以unlist()
结果。模式的想法是抓住所有不是一个点或一个&#34; /&#34;紧接着&#34; .com&#34;。