【发布时间】:2013-03-22 20:14:59
【问题描述】:
我有多个文本,每个文本都可能包含对一个或多个 Web 链接的引用。例如:
text1= "s@1212a as www.abcd.com asasa11".
如何提取:
"www.abcd.com"
从R中的这个文本?换句话说,我希望提取以www 开头并以.com 结尾的模式
【问题讨论】:
标签: r
我有多个文本,每个文本都可能包含对一个或多个 Web 链接的引用。例如:
text1= "s@1212a as www.abcd.com asasa11".
如何提取:
"www.abcd.com"
从R中的这个文本?换句话说,我希望提取以www 开头并以.com 结尾的模式
【问题讨论】:
标签: r
regmatches 这种方法使用regexpr/grepgexpr 和regmatches。我扩展了测试数据以包含更多示例。
text1 <- c("s@1212a www.abcd.com www.cats.com",
"www.boo.com",
"asdf",
"blargwww.test.comasdf")
# Regular expressions take some practice.
# check out ?regex or the wikipedia page on regular expressions
# for more info on creating them yourself.
pattern <- "www\\..*?\\.com"
# Get information about where the pattern matches text1
m <- gregexpr(pattern, text1)
# Extract the matches from text1
regmatches(text1, m)
这给了
> regmatches(text1, m) ##
[[1]]
[1] "www.abcd.com" "www.cats.com"
[[2]]
[1] "www.boo.com"
[[3]]
character(0)
[[4]]
[1] "www.test.com"
注意它返回一个列表。如果我们想要一个向量,您可以在结果上使用unlist。这是因为我们使用了gregexpr,这意味着我们的字符串中可能有多个匹配项。如果我们知道最多有一个匹配项,我们可以改用regexpr
> m <- regexpr(pattern, text1)
> regmatches(text1, m)
[1] "www.abcd.com" "www.boo.com" "www.test.com"
但是请注意,这会将所有结果作为向量返回,并且仅从每个字符串返回一个结果(请注意 www.cats.com 不在结果中)。不过,总的来说,我认为这两种方法中的任何一种都比gsub 方法更可取,因为如果没有找到结果,这种方法将返回整个输入。例如看一下:
> gsub(text1, pattern=".*(www\\..*?\\.com).*", replace="\\1")
[1] "www.abcd.com" "www.boo.com" "asdf" "www.test.com"
即使在将模式修改为更健壮一点之后也是如此。我们仍然在结果中得到“asdf”,即使它显然与模式不匹配。
无耻愚蠢的自我推销:regmatches 是在 R 2.14 中引入的,所以如果你坚持使用早期版本的 R,你可能会不走运。除非你能够安装 future2.14 包 from my github repo,它为 2.14 中引入的功能提供了一些支持到早期版本的 R。
strapplyc。与上面 ## 给出相同结果的另一种方法是:
library(gsubfn)
strapplyc(test1, pattern)
正则表达式下面是一些关于如何破译正则表达式的解释:
pattern <- "www\\..*?\\.com"
解释:
www 匹配 www 部分
\\. 我们需要使用\\ 转义一个实际的“点”字符,因为普通的. 表示正则表达式中的“任何字符”。
.*? . 代表任何字符,* 告诉匹配 0 次或多次,? 跟在 * 之后告诉它不要贪心。否则,“asdf www.cats.com www.dogs.com asdf”会将所有“www.cats.com www.dogs.com”作为一个匹配项进行匹配,而不是识别出其中有两个匹配项。
\\. 再次我们需要转义一个实际的点字符
com这部分匹配我们要匹配的结尾'com'
总而言之,它说:从 www 开始。然后匹配任何字符,直到到达第一个“.com”
【讨论】:
查看 gsub 函数:
x = "s@1212a as www.abcd.com asasa11"
gsub(x=x, pattern=".*(www.*com).*", replace="\\1")
基本思路是将要保留的 txt 括在括号中,然后用它替换整行。 gsub "\\1" 的替换参数指的是括号中的内容。
【讨论】:
\\1的含义需要更多解释。
这里的解决方案很棒而且很基础。对于那些想要快速解决方案的人,您可以使用qdap 的genXtract。这个函数基本上需要一个左元素和一个右元素,它将提取两者之间的所有内容。通过设置with = TRUE,它将包含这些元素:
text1 <- c("s@1212a www.abcd.com www.cats.com",
"www.boo.com",
"asdf",
"http://www.talkstats.com/ and http://stackoverflow.com/",
"blargwww.test.comasdf")
library(qdap)
genXtract(text1, "www.", ".com", with=TRUE)
## > genXtract(text1, "www.", ".com", with=TRUE)
## $`www. : .com1`
## [1] "www.abcd.com" "www.cats.com"
##
## $`www. : .com2`
## [1] "www.boo.com"
##
## $`www. : .com3`
## character(0)
##
## $`www. : .com4`
## [1] "www.talkstats.com"
##
## $`www. : .com5`
## [1] "www.test.com"
PS 如果您查看该函数的代码,它是 Dason 解决方案的包装器。
【讨论】: