R 提取可能多次出现或根本不出现的字符串元素
从URL的字符向量开始。目标是以公司名称结束,这意味着在下面的示例中,列中只包含R 提取可能多次出现或根本不出现的字符串元素,r,substring,regex-lookarounds,strsplit,R,Substring,Regex Lookarounds,Strsplit,从URL的字符向量开始。目标是以公司名称结束,这意味着在下面的示例中,列中只包含“test”、“example”和“sample” urls <- c("http://grand.test.com/", "https://example.com/", "http://.big.time.sample.com/") 我的下一步是使用链式gsub()调用删除http://和https://部分: urls <- gsub("^http://", "", gsub
“test”
、“example”
和“sample”
urls <- c("http://grand.test.com/", "https://example.com/",
"http://.big.time.sample.com/")
我的下一步是使用链式gsub()
调用删除http://
和https://
部分:
urls <- gsub("^http://", "", gsub("^https://", "", urls))
urls
# [1] "grand.test" "example" ".big.time.sample"
可能是一个ifelse()
调用,它计算剩余的周期数,并且仅在存在多个周期时使用strsplit?还请注意,公司名称前可能有两个或多个句点。我不知道如何环顾四周,这可能会解决我的问题。但事实并非如此
strsplit(urls, split="(?=\\.)", perl=T)
谢谢您的建议。我认为应该有更简单的建议,但这是可行的:
sub('.*[.]','',sub('https?:[/]+[.]?(.*)[.]com[/]','\\1',urls))
[1] "test" "example" "sample"
其中“url”是你第一个url的矢量。我认为有一种方法可以把“.com”前面的单词提取出来,但可能会给出一个想法
sub(".com", "", regmatches(urls, gregexpr("(\\w+).com", urls)))
使用strsplit可能也值得一试:
sapply(strsplit(urls,"/|\\."),function(x) tail(x,2)[1])
#[1] "test" "example" "sample"
您可以使用
stringr::word()
,以及basename()
basename()
在处理URL时非常方便
> library(stringr)
> word(basename(urls), start = -2, sep = "\\.")
# [1] "test" "example" "sample"
basename(URL)
[1] "grand.test.com" "example.com" ".big.time.sample.com"
然后,在
word()
函数中,我们从末尾取第二个单词(start=-2
),因为分隔符是
(sep=“\\\”
)。因为您从来没有足够的正则表达式选项,这里是使用函数的
如果只需要返回值的简单向量,可以
unlist()
结果。该模式的思想是抓住“.com”前面不是点或“/”的所有内容。以下是一种比其他方法更容易理解和概括的方法:
pat = "(.*?)(\\w+)(\\.com.*)"
gsub(pat, "\\2", urls)
它的工作原理是将每个字符串分成三个捕获组,这些捕获组一起匹配整个字符串,然后替换回您想要的捕获组(2)
pat = "(.*?)(\\w+)(\\.com.*)"
# ^ ^ ^
# | | |
# (1) (2) (3)
编辑(添加?
修改器的解释):
请注意,捕获组(1)
需要包含“ungreedy”或“minimal”量词?
()。它本质上告诉正则表达式引擎匹配尽可能多的字符。。。不使用任何可能成为以下捕获组一部分的内容(2)
如果没有尾随的
?
,重复量词在默认情况下是贪婪的;在本例中,一个贪婪的捕获组,(.*)
,因为它匹配任意数量的任何类型的字符,将“吃掉”字符串中的所有字符,而不给其他两个捕获组留下任何字符——这不是我们想要的行为 这是一个极好的例子。有用的答案和一些解释产生得非常快
回答我自己的问题并不能说明我在做什么。我想感谢撰稿人,给一些可能帮助其他人看这个问题的东西,并解释为什么我选择了一个答案。一个评论似乎不正确,也不够长
下面汇总了每个答案以及我的(谦虚的,并且很高兴被纠正)解释,其中几个包含了回答者的解释。仔细研究答案教会了我很多,并帮助我选择了一个更喜欢的答案。其他人使用非base-R函数,其中一个是创建的函数,它可能很好,但并不容易获得。我喜欢第二个答案,因为它只使用了子功能,但我把月桂花环送给了第五个,因为它优雅地使用了两种技巧,我很高兴学习到这两种技巧。谢谢大家
答案1
gregexpr
使用特殊单词字符“w+”
,在“.com”
之前查找任何一个或多个单词,并返回包含长度和使用字节的列表
regmatches
获取找到的gregexpr
并仅返回已识别的字符串
sub
从每个字符串中删除第一个“.com”[我不确定为什么gsub不起作用,但当您只需要第一个实例时,全局sub可能是一个风险]
ANS 2
内部子模块通过问号特殊字符?处理“http:”和“https:”,这允许“s”是可选的
然后,内部子函数用一个字符类处理一个或多个“/”,该字符类仅包含一个正斜杠,但由“+”
扩展,即在http中两次://
右侧内部子正则表达式读取的下一部分包括任意数量的字符,这些字符是可选的,“[.]?
接下来,将“com”之前的句点放在括号中,而不是转义它
然后是“com”,后跟正斜杠[我不确定我是否理解该部分]
“\\1”仅保留子函数提取内容的第一部分
所有上述操作都返回以下内容:
[1] "grand.test" "example" "big.time.sample"
最左边的子函数获取内部子函数的结果,并删除括号内句点前面带有“*”的所有字符
答案3
首先,strsplit
使用垂直管道(生成列表)以正斜杠或句点分隔每个字符串
[[1]]
[1] "http:" "" "grand" "test" "com"
[[2]]
[1] "https:" "" "example" "com"
[[3]]
[1] "http:" "" "" "big" "time" "sample" "com"
接下来,一个匿名函数使用tail
函数查找每个字符串中的最后两个元素,并选择第一个元素,从而整齐地删除每个“.com”
用sapply函数包装这两个步骤将匿名函数的操作矢量化为所有三个字符串
ANS 4
basename
函数返回
[1] "grand.test.com" "example.com" ".big.time.sample.com"
从对basename()
的帮助中,我们了解到“basename将删除最后一个路径分隔符(如果有)之前的所有路径”,这将整齐地删除http://和https://元素
然后,word()
函数使用负数运算符(start=-2)从末尾提取第二个“word”,前提是se
sub(".com", "", regmatches(urls, gregexpr("(\\w+).com", urls)))
sub('.*[.]','', sub('https?:[/]+[.]?(.*)[.]com[/]','\\1',urls))
[1] "grand.test" "example" "big.time.sample"
sapply(strsplit(urls, "/|\\."), function(x) tail(x,2)[1])
[[1]]
[1] "http:" "" "grand" "test" "com"
[[2]]
[1] "https:" "" "example" "com"
[[3]]
[1] "http:" "" "" "big" "time" "sample" "com"
library(stringr)
word(basename(urls), start = -2, sep = "\\.")
[1] "grand.test.com" "example.com" ".big.time.sample.com"
pat = "(.*?)(\\w+)(\\.com.*)"
gsub(pat, "\\2", urls)
pat = "(.*?)(\\w+)(\\.com.*)"
# ^ ^ ^
# | | |
# (1) (2) (3)
regcapturedmatches(urls, regexpr("([^.\\/]+)\\.com", urls, perl=T))